尝试自动装配 class 时 spring bean 配置出错,将 Morphia 与 MongoDB 结合使用
Error with spring bean configuraion while trying to autowire class that usind Morphia with MongoDB
我有一个使用外观的控制器,它使用 DAO 将一些值保存到数据库中,这里是结构:
控制器:
@Controller
@RequestMapping("stores/Items")
@ContextConfiguration("classpath:application-context-core-production.xml")
public class ItemsController {
@Autowired
IItemsFacade itemsFacade;
}
门面:
@Service
public class ItemsFacade implements IItemsFacade {
@Autowired
ItemDAO itemDAO;
}
DAO:
@Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{
@Autowired
public ItemDAO(MongoClient mongoClient, Morphia morphia, String mongoDB) {
super(mongoClient, morphia, mongoDB);
}
}
应用程序上下文核心-production.xml:
<context:component-scan base-package="com.salegroup.*" />
<!-- Setup Mongo and Morphia -->
<mongo:mongo host="localhost" port="27017" />
<bean class="java.lang.String" id="mongoDB">
<constructor-arg value="sale" />
</bean>
<bean class="com.mongodb.MongoClient" id="mongo" />
<bean class="org.mongodb.morphia.Morphia" id="morphia" />
<bean class="com.salegroup.persistence.dao.item.impl.ItemDAO" id="itemDAO">
<constructor-arg ref="mongo" index="0" />
<constructor-arg ref="morphia" index="1" />
<constructor-arg ref="mongoDB" index="2" />
</bean>
DAO 应该连接到 mongoDB,我正在使用 xml 配置来创建 MongoClient 和 Morfia。
在嵌入式 tomcat 服务器中尝试 运行 时出现以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemDAO' defined in file
[...\ItemDAO.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.mongodb.morphia.Morphia]: : No qualifying bean of type [org.mongodb.morphia.Morphia]
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.mongodb.morphia.Morphia] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
我错过了什么?必须说以防万一我要从立面移除 class 一切正常(...dahhh..)。
除此之外,测试也很有效,我正在将有效连接连接到数据库中。
有什么想法吗?
你的代码有两个问题
- 注解 @ContextConfiguration 不专用于导入 xml 配置文件,集成测试除外
@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests. API
- xml 配置文件永远不会被解析,这就是为什么没有发现 Morphia 实例被自动装配的原因,即使发生这种情况并且您的 xml 配置文件被解析,您将获得 2 个 ItemDAO 实例在你的容器中,你可能不想要
如果您正在为 spring 使用基于 Annptation 的配置,这就是您要执行的操作
第一种方法
在你的Configurationclass(用@Configuration注解的那个)你这样注解
@Configuration
@ImportResource("classpath:application-context-core-production.xml")
public class AppConfig{...}
您从 class ItemDAO
中删除注释 @Repository 和 @Autowired
第二种方法
完全忘记 xml 配置并在这样的注释中完成所有操作
@Configuration
@PropertySource("classpath:mongo.properties")
public class AppConfig{
// some methods ...
@Bean
public Mongo mongo(@Value("${mongo.host.addr}")String host,@Value("${mongo.host.port}")int port){
return new Mongo(host,port);
}
@Bean
public Morphia morphia(){
return new Morphia();
}
}
在您的存储库中 class
@Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{
@Autowired
public ItemDAO(MongoClient mongoClient, Morphia morphia,@Value("${mongo.mongoDB}") String mongoDB) {
super(mongoClient, morphia, mongoDB);
}
}
在你的class路径中mongo.properties
mongo.DB=sale
mongo.host.addr=localhost
mongo.host.port=27017
我有一个使用外观的控制器,它使用 DAO 将一些值保存到数据库中,这里是结构:
控制器:
@Controller
@RequestMapping("stores/Items")
@ContextConfiguration("classpath:application-context-core-production.xml")
public class ItemsController {
@Autowired
IItemsFacade itemsFacade;
}
门面:
@Service
public class ItemsFacade implements IItemsFacade {
@Autowired
ItemDAO itemDAO;
}
DAO:
@Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{
@Autowired
public ItemDAO(MongoClient mongoClient, Morphia morphia, String mongoDB) {
super(mongoClient, morphia, mongoDB);
}
}
应用程序上下文核心-production.xml:
<context:component-scan base-package="com.salegroup.*" />
<!-- Setup Mongo and Morphia -->
<mongo:mongo host="localhost" port="27017" />
<bean class="java.lang.String" id="mongoDB">
<constructor-arg value="sale" />
</bean>
<bean class="com.mongodb.MongoClient" id="mongo" />
<bean class="org.mongodb.morphia.Morphia" id="morphia" />
<bean class="com.salegroup.persistence.dao.item.impl.ItemDAO" id="itemDAO">
<constructor-arg ref="mongo" index="0" />
<constructor-arg ref="morphia" index="1" />
<constructor-arg ref="mongoDB" index="2" />
</bean>
DAO 应该连接到 mongoDB,我正在使用 xml 配置来创建 MongoClient 和 Morfia。
在嵌入式 tomcat 服务器中尝试 运行 时出现以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'itemDAO' defined in file
[...\ItemDAO.class]: Unsatisfied dependency expressed through constructor argument with index 1 of type [org.mongodb.morphia.Morphia]: : No qualifying bean of type [org.mongodb.morphia.Morphia]
found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.
Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.mongodb.morphia.Morphia] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
我错过了什么?必须说以防万一我要从立面移除 class 一切正常(...dahhh..)。
除此之外,测试也很有效,我正在将有效连接连接到数据库中。
有什么想法吗?
你的代码有两个问题
- 注解 @ContextConfiguration 不专用于导入 xml 配置文件,集成测试除外
@ContextConfiguration defines class-level metadata that is used to determine how to load and configure an ApplicationContext for integration tests. API
- xml 配置文件永远不会被解析,这就是为什么没有发现 Morphia 实例被自动装配的原因,即使发生这种情况并且您的 xml 配置文件被解析,您将获得 2 个 ItemDAO 实例在你的容器中,你可能不想要
如果您正在为 spring 使用基于 Annptation 的配置,这就是您要执行的操作
第一种方法
在你的Configurationclass(用@Configuration注解的那个)你这样注解
@Configuration @ImportResource("classpath:application-context-core-production.xml") public class AppConfig{...}
您从 class ItemDAO
中删除注释 @Repository 和 @Autowired
第二种方法
完全忘记 xml 配置并在这样的注释中完成所有操作
@Configuration
@PropertySource("classpath:mongo.properties")
public class AppConfig{
// some methods ...
@Bean
public Mongo mongo(@Value("${mongo.host.addr}")String host,@Value("${mongo.host.port}")int port){
return new Mongo(host,port);
}
@Bean
public Morphia morphia(){
return new Morphia();
}
}
在您的存储库中 class
@Repository
public class ItemDAO extends BasicDAO<Item, ObjectId> implements IItemDAO{
@Autowired
public ItemDAO(MongoClient mongoClient, Morphia morphia,@Value("${mongo.mongoDB}") String mongoDB) {
super(mongoClient, morphia, mongoDB);
}
}
在你的class路径中mongo.properties
mongo.DB=sale
mongo.host.addr=localhost
mongo.host.port=27017