[SPRING] AnnotationConfigApplicationContext 및 부모 컨텍스트
SPRINGAnnotationConfigApplicationContext 및 부모 컨텍스트
AnnotationConfigApplicationContext를 사용하여 컨텍스트 계층 구조를 정의하려고 할 때 문제가 있습니다.
문제는 beanRefContext.xml 안에 모듈 컨텍스트를 정의하고 다른 컨텍스트 (XML / Annotated 기반)로 'parent'속성을 설정할 때입니다.
예:
모듈 A의 beanRefContext.xml
<bean id="moduleA_ApplicationContext" class="org.springframework.context.support.ClassPathXmlApplicationContext"> <property name="configLocations"> <list> <value>classpath:db-context.xml</value> </list> </property> </bean>
db-context.xml
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="org.h2.Driver" p:url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;TRACE_LEVEL_SYSTEM_OUT=2"/> <!-- Hibernate Session Factory --> <bean name="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="useTransactionAwareDataSource" value="true"/> <property name="packagesToScan"> <list> <value>com.example.model</value> </list> </property> <property name="hibernateProperties"> <!-- hibernate props --> </property> </bean>
모듈 B의 beanRefContext.xml
<bean id="moduleB_ApplicationContext" class="org.springframework.context.annotation.AnnotationConfigApplicationContext" > <property name="parent" ref="moduleA_ApplicationContext"/> <constructor-arg> <list> <value>com.example.dao</value> </list> </constructor-arg> </bean>
FooHibernateDao
class FooHibernateDao implements FooDao { @Autowired @Qualifier("sessionFactory") private SessionFactory sessionsFactory; // CRUD methods }
모듈 B 응용 프로그램 컨텍스트가 모듈 A 응용 프로그램 컨텍스트에 정의 된 bean을 찾지 못합니다. AnnotationConfigApplicationContext의 코드를 살펴보면 스캐닝 프로세스가 부모를 참조로 사용하여 콩을 처리하지 못하는 것처럼 보입니다.
내가 틀린 일이 있거나 어노테이션 구성으로 계층 구조를 만들려는 시도가 불가능합니까?
해결법
-
==============================
1.이 문제는 AnnotationConfigApplicationContext의 생성자가 검사를 수행한다는 사실에서 기인합니다. 따라서 부모는이 단계에서 설정되지 않습니다. 부모가 속성에 의해 설정되므로 검사가 완료된 후에 만 설정됩니다. 따라서 빈을 찾지 못한 이유입니다.
이 문제는 AnnotationConfigApplicationContext의 생성자가 검사를 수행한다는 사실에서 기인합니다. 따라서 부모는이 단계에서 설정되지 않습니다. 부모가 속성에 의해 설정되므로 검사가 완료된 후에 만 설정됩니다. 따라서 빈을 찾지 못한 이유입니다.
기본 AnnotationConfigApplicationContext 빈에는 부모 팩토리를 사용하는 생성자가 없습니다. 그 이유는 확실하지 않습니다.
일반 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>
-
==============================
2.XML을 하위 컨텍스트에 사용하지 마십시오. ctx.setParent를 사용하고 ctx.register를 사용하십시오. 이렇게 :
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; } }
-
==============================
3.나는 같은 문제를 겪는다.
나는 같은 문제를 겪는다.
또 다른 가능성은 Java에서 AnnotationConfigApplicationContext를 인스턴스화하는 경우 AnnotationConfigApplicationContext를 확장하고 필요한 생성자 만 추가하거나 프로그램 적으로 컨텍스트를 빌드하는 것입니다.
-
==============================
4.내가 한 일은 다음과 같다.
내가 한 일은 다음과 같다.
BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance("classpath:beanRefContext.xml"); BeanFactoryReference parentContextRef = locator.useBeanFactory("ear.context"); ApplicationContext parentContext = (ApplicationContext) parentContextRef.getFactory(); childContext.setParent(parentContext);
그리고 그것은 무엇일까요?
추신 : 누구든지 classpath : beanRefContext.xml을 @Configuration 클래스로 대체하는 방법을 알고 있다면 알려주십시오.
from https://stackoverflow.com/questions/4364221/annotationconfigapplicationcontext-and-parent-context by cc-by-sa and MIT license