开发者社区> 问答> 正文

Spring整合MangoDB原生驱动

最近在工作中用到了MongoDB,当然作为一个小diao丝员,只能在别人构建好的框架(Spring date Mongo)上进行增删改查操作,闲来之余打算自己研究一下,在使用spring整合MangoDB原生驱动时候,出现了一些问题,(无法用spring生成数据源的bean)望大牛指导一下,万分感谢

首先说一句,本文中的代码基本是转自大牛@zhuyuping ,版权归其所有,小弟不敢贪妄~

各位大神,问题来了:当我运行测试类的时候,不用Spring生成bean并把数据源参数都配置java代码中直接new实例测试一切正常,而用spring生成bean的时候会,创建id=“mongodo”的bean 这时会报类造型异常:

原因是生成我注入数据源bean类造型异常 有感兴趣的大牛跟着小弟的思路一点一点的来~

谢谢各位大牛,言归正传,下面开始代码一步一步引入问题

第一个是数据源:
package factory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
 
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.Mongo;
import com.mongodb.MongoOptions;
import com.mongodb.ServerAddress;
 
 
public class MongoDBFactoryBean implements FactoryBean<Mongo>,InitializingBean,DisposableBean{
    private Mongo mongo;
 
    private String host;
     
    private boolean autoConnectRetry;
     
    private int connectionsPerHost;//每个主机的连接数
     
    private int threadsAllowedToBlockForConnectionMultiplier;//线程队列数,它以上面的connectionsperHost
    //值相乘的结果就是线程队列最大值。如果线程排满了队列就会抛出“out of semaphores to get db”错误
     
    private boolean fsync;
     
    private int maxWaitTime ;
     
    private int connectTimeout ;
 
    public Mongo getMongo() {
        return mongo;
    }
 
    public void setMongo(Mongo mongo) {
        this.mongo = mongo;
    }
 
    public String getHost() {
        return host;
    }
 
    public void setHost(String host) {
        this.host = host;
    }
 
    public boolean isAutoConnectRetry() {
        return autoConnectRetry;
    }
 
    public void setAutoConnectRetry(boolean autoConnectRetry) {
        this.autoConnectRetry = autoConnectRetry;
    }
 
    public int getConnectionsPerHost() {
        return connectionsPerHost;
    }
 
    public void setConnectionsPerHost(int connectionsPerHost) {
        this.connectionsPerHost = connectionsPerHost;
    }
 
    public int getThreadsAllowedToBlockForConnectionMultiplier() {
        return threadsAllowedToBlockForConnectionMultiplier;
    }
 
    public void setThreadsAllowedToBlockForConnectionMultiplier(
            int threadsAllowedToBlockForConnectionMultiplier) {
        this.threadsAllowedToBlockForConnectionMultiplier = threadsAllowedToBlockForConnectionMultiplier;
    }
 
    public boolean isFsync() {
        return fsync;
    }
 
    public void setFsync(boolean fsync) {
        this.fsync = fsync;
    }
 
    public int getMaxWaitTime() {
        return maxWaitTime;
    }
 
    public void setMaxWaitTime(int maxWaitTime) {
        this.maxWaitTime = maxWaitTime;
    }
 
    public int getConnectTimeout() {
        return connectTimeout;
    }
 
    public void setConnectTimeout(int connectTimeout) {
        this.connectTimeout = connectTimeout;
    }
 
    public void destroy() throws Exception {
         
        this.mongo.close();
         
         
    }
 
    public void afterPropertiesSet() throws Exception {
         
        ServerAddress server = new ServerAddress(host);  
 
        MongoOptions options = new MongoOptions();  
 
        options.autoConnectRetry = this.autoConnectRetry;  
 
        options.connectionsPerHost = this.connectionsPerHost;  
 
        options.threadsAllowedToBlockForConnectionMultiplier = this.threadsAllowedToBlockForConnectionMultiplier;  
 
        options.fsync = this.fsync;  
 
        options.connectTimeout=this.connectTimeout;  
 
        options.maxWaitTime=this.maxWaitTime;  
         
        this.mongo = new Mongo(server, options);  
 
         
    }
 
    public Mongo getObject() throws Exception {
        ServerAddress server = new ServerAddress(host);  
 
        MongoOptions options = new MongoOptions();  
 
        options.autoConnectRetry = this.autoConnectRetry;  
 
        options.connectionsPerHost = this.connectionsPerHost;  
 
        options.threadsAllowedToBlockForConnectionMultiplier = this.threadsAllowedToBlockForConnectionMultiplier;  
 
        options.fsync = this.fsync;  
 
        options.connectTimeout=this.connectTimeout;  
 
        options.maxWaitTime=this.maxWaitTime;
        mongo = new Mongo(server, options);  
 
         
         return mongo; 
    }
 
    public Class<?> getObjectType() {
     
         return Mongo.class; 
    }
 
    public boolean isSingleton() {
     
         return true; 
    }
     public  DB getDB(String dbname) throws Exception {  
          
         return getObject().getDB(dbname);  
 
    }  
 
     public  DBCollection getCollection(String dbname, String collection) throws Exception { 
          
         return getDB(dbname).getCollection(collection);  
 
    }  
 
     
 
}
第二步 具体实现调用数据源

package service;
 
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
 
 
 
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
 
 
import factory.MongoDBFactoryBean;
 
  public class UserService  implements IUserService    {  
 
  protected static Logger logger = Logger.getLogger("service");  
  private MongoDBFactoryBean mongoDBFactoryBean ;
 
  public void setMongoDBFactoryBean(MongoDBFactoryBean mongoDBFactoryBean) {
    this.mongoDBFactoryBean = mongoDBFactoryBean;
}
//private MongoDBFactoryBean mongoDBFactoryBean  = new MongoDBFactoryBean();
    public List<DBObject> getAll() {
 
        DBCollection coll = null;
        try {
            System.out.println("789");
            coll = mongoDBFactoryBean.getCollection("wechat", "text");
        } catch (Exception e) {
         
            e.printStackTrace();
        }
         
        DBCursor cur = coll.find();//
         
     List<DBObject> items = new ArrayList<DBObject>();
      
           while(cur.hasNext()) {
           
            items.add(cur.next());
           }
             
            
     return items;
    }
     
     
      
}

接口:

package service;
 
import java.util.List;
 
import com.mongodb.DBObject;
 
public interface IUserService {
     
    public List<DBObject> getAll();
}
 

测试类:

package service;
 
import java.util.List;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
import com.mongodb.DBObject;
 
public class run { 
public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext.xml");
    UserService a=(UserService) ac.getBean("mongodo") ; 
    List<DBObject> b = a.getAll();
    System.out.println(b.toString());
}
}
 

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="mongobean" class="factory.MongoDBFactoryBean" >
            <property name="host" value="201.112.168.7"></property>
            <property name="autoConnectRetry" value= "true"></property> 
            <property name="connectionsPerHost" value="10"></property>
            <property name="threadsAllowedToBlockForConnectionMultiplier" value="10"></property>
            <property name="fsync" value="true"></property>
            <property name="maxWaitTime" value="120000"></property>
            <property name="connectTimeout" value="1000"></property>
            </bean>
    <bean id="mongodo" class = "service.UserService">
        <property name = "mongoDBFactoryBean"
            ref = "mongobean">
                </property>
    </bean>
    
 
</beans>

各位大神,问题来了:当我运行测试类的时候,不用Spring生成bean并把数据源参数都配置java代码中直接new实例测试一切正常,而用spring生成bean的时候会,创建id=“mongodo”的bean 这时会报类造型异常:

  原因是生成我注入数据源bean类造型异常

   Failed to convert property value of type 'com.mongodb.Mongo' to required type 'factory.MongoDBFactoryBean' for property 'mongoDBFactoryBean

五月 06, 2014 2:04:09 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@f5e12: startup date [Tue May 06 14:04:09 CST 2014]; root of context hierarchy
五月 06, 2014 2:04:09 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
五月 06, 2014 2:04:09 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3b8716cc: defining beans [mongobean,mongodo]; root of factory hierarchy
五月 06, 2014 2:04:09 下午 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3b8716cc: defining beans [mongobean,mongodo]; root of factory hierarchy
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongodo' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.mongodb.Mongo' to required type 'factory.MongoDBFactoryBean' for property 'mongoDBFactoryBean'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.mongodb.Mongo] to required type [factory.MongoDBFactoryBean] for property 'mongoDBFactoryBean': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:580)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at service.run.main(run.java:12)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.mongodb.Mongo' to required type 'factory.MongoDBFactoryBean' for property 'mongoDBFactoryBean'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.mongodb.Mongo] to required type [factory.MongoDBFactoryBean] for property 'mongoDBFactoryBean': no matching editors or conversion strategy found
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:462)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:499)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:493)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1371)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1330)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    ... 11 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [com.mongodb.Mongo] to required type [factory.MongoDBFactoryBean] for property 'mongoDBFactoryBean': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:231)
    at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:447)
    ... 17 more

原因是生成我注入数据源bean类造型异常

请各位大神快快现身吧,小弟纠结两天了,万分感谢,万分感谢,万分感谢,万分感谢,万分感谢,万分感谢,万分感谢啊!!!

救救小弟我吧!!

展开
收起
a123456678 2016-03-17 10:14:14 2528 0
1 条回答
写回答
取消 提交回答
  • 错误来自Spring IOC 注入方式的不同,在大牛的源代码中使用的是factoryBean 的方式进行注入的

    我这边拿过来用的工厂方法注入却依然继承了factoryBean<>, 所以会产生错误,so把MongoDbFactoryBean 中继承的factoryBean<>,去掉就可以了

    2019-07-17 19:04:37
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第20讲):经典面试题与阿里等名企内部招聘求职面试技巧 立即下载
微服务架构模式与原理Spring Cloud开发实战 立即下载
阿里特邀专家徐雷Java Spring Boot开发实战系列课程(第18讲):制作Java Docker镜像与推送到DockerHub和阿里云Docker仓库 立即下载

相关实验场景

更多