我正试图用一个问题来定义一个上下文层次结构AnnotationConfigApplicationContext
。
问题是在内部定义模块上下文beanRefContext.xml
并使用另一个上下文(基于XML / Annotated)设置'parent'属性。
例:
模块A中的beanRefContext.xml
<bean id =“moduleA_ApplicationContext”
类= “org.springframework.context.support.ClassPathXmlApplicationContext”>
<property name =“configLocations”>
<列表>
<值>类路径:DB-context.xml中</值>
</列表>
</属性>
</豆>
DB-的context.xml
<bean id =“dataSource”
类= “org.apache.commons.dbcp.BasicDataSource”
破坏法=“接近”
号码:driverClassName = “org.h2.Driver”
号码:URL = “JDBC:H2:MEM:TESTDB; DB_CLOSE_DELAY = -1; MODE = MySQL的; TRACE_LEVEL_SYSTEM_OUT = 2”/>
<! - Hibernate Session Factory - >
<bean name =“sessionFactory”
类= “org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>
<property name =“dataSource”ref =“dataSource”/>
<property name =“useTransactionAwareDataSource”value =“true”/>
<property name =“packagesToScan”>
<列表>
<值> com.example.model </值>
</列表>
</属性>
<property name =“hibernateProperties”>
<! - hibernate props - >
</属性>
</豆>
模块B中的beanRefContext.xml
<bean id =“moduleB_ApplicationContext”
class =“org.springframework.context.annotation.AnnotationConfigApplicationContext”>
<property name =“parent”ref =“moduleA_ApplicationContext”/>
<构造精氨酸>
<列表>
<值> com.example.dao </值>
</列表>
</构造精氨酸>
</豆>
FooHibernateDao
class FooHibernateDao实现FooDao {
@Autowired
@Qualifier( “SessionFactory的”)
private SessionFactory sessionsFactory;
// CRUD方法
}
模块B应用程序上下文无法找到模块A应用程序上下文中定义的bean。
从查看代码来看AnnotationConfigApplicationContext
,扫描过程似乎不使用父作为解析bean的参考。
有什么我做错了或者我的注释配置是不可能尝试创建层次结构?
发布于 2019-06-27 10:32:25
不要将XML用于子上下文。使用ctx.setParent然后使用ctx.register。像这样:
public class ParentForAnnotationContextExample {
public static void main(String[] args) {
ApplicationContext parentContext = new AnnotationConfigApplicationContext(ParentContext.class);
AnnotationConfigApplicationContext childContext = new AnnotationConfigApplicationContext();
childContext.setParent(parentContext);
childContext.register(ChildContext.class); //don't add in the constructor, otherwise the @Inject won't work
childContext.refresh();
System.out.println(childContext.getBean(ParentBean.class));
System.out.println(childContext.getBean(ChildBean.class));
childContext.close();
}
@Configuration
public static class ParentContext {
@Bean ParentBean someParentBean() {
return new ParentBean();
}
}
@Configuration
public static class ChildContext {
@Bean ChildBean someChildBean() {
return new ChildBean();
}
}
public static class ParentBean {}
public static class ChildBean {
//this @Inject won't work if you use ChildContext.class in the child AnnotationConfigApplicationContext constructor
@Inject private ParentBean injectedFromParentCtx;
}
}
发布于 2019-06-27 11:11:01
问题源于AnnotationConfigApplicationContext的构造函数执行扫描的事实。因此,父级未设置在此阶段,仅在扫描完成后设置,因为父级由属性设置 - 因此它找不到您的bean的原因。
默认的AnnotationConfigApplicationContext bean没有构建器来获取父工厂 - 不知道为什么。
您可以使用常规的基于xml的应用程序上下文并在其中配置注释扫描,也可以创建一个自定义的fatory bean来创建注释应用程序上下文。这将指定父引用,然后执行扫描。
看看来源......
工厂看起来像这样:
public class AnnotationContextFactory implements FactoryBean<ApplicationContext> {
private String[] packages;
private ApplicationContext parent;
@Override
public ApplicationContext getObject() throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.setParent(parent);
context.scan(packages);
context.refresh();
return context;
}
@Override
public Class<ApplicationContext> getObjectType() {
return ApplicationContext.class;
}
@Override
public boolean isSingleton() {
return true;
}
public void setPackages(String... args) {
this.packages = args;
}
public void setParent(ApplicationContext parent) {
this.parent = parent;
}
}
你的bean定义:
<bean id="moduleB_ApplicationContext" class="za.co.test2.AnnotationContextFactory">
<property name="parent" ref="moduleA_ApplicationContext" />
<property name="packages">
<list>
<value>za.co.test2</value>
</list>
</property>
</bean>
https://stackoverflow.com/questions/-100009104
复制相似问题