AnnotationConfigApplicationContext 和父上下文 [英] AnnotationConfigApplicationContext and parent context

查看:49
本文介绍了AnnotationConfigApplicationContext 和父上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试使用 AnnotationConfigApplicationContext 定义上下文层次结构时遇到问题.

问题在于在 beanRefContext.xml 中定义模块上下文并使用另一个上下文(基于 XML/注释)设置父"属性时.

示例:

模块 A 中的 beanRefContext.xml

<前><bean id="moduleA_ApplicationContext"class="org.springframework.context.support.ClassPathXmlApplicationContext"><列表><value>classpath:db-context.xml</value>

db-context.xml

<前><bean id="数据源"class="org.apache.commons.dbcp.BasicDataSource"销毁方法=关闭"p:driverClassName="org.h2.Driver"p:url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;TRACE_LEVEL_SYSTEM_OUT=2"/><!-- 休眠会话工厂--><bean 名称="sessionFactory"class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><属性名称="dataSource" ref="dataSource"/><property name="useTransactionAwareDataSource" value="true"/><列表><value>com.example.model</value><property name="hibernateProperties"><!-- 休眠道具-->

模块 B 中的 beanRefContext.xml

<前><bean id="moduleB_ApplicationContext"class="org.springframework.context.annotation.AnnotationConfigApplicationContext" ><property name="parent" ref="moduleA_ApplicationContext"/><构造函数参数><列表><value>com.example.dao</value></constructor-arg>

FooHibernateDao

<前>FooHibernateDao 类实现了 FooDao {@自动连线@Qualifier("sessionFactory")私人会话工厂会话工厂;//CRUD 方法}

模块 B 应用程序上下文无法找到模块 A 应用程序上下文中定义的 bean.
AnnotationConfigApplicationContext的代码来看,扫描过程似乎没有使用parent作为解析bean的引用.

是不是我做错了什么,或者我尝试通过注释配置创建层次结构是不可能的?

解决方案

问题源于 AnnotationConfigApplicationContext 的构造函数进行扫描.因此在此阶段未设置父级,它仅在扫描完成后设置,因为父级由属性设置 - 这就是它找不到您的 bean 的原因.

默认的 AnnotationConfigApplicationContext bean 没有采用父工厂的构造函数 - 不知道为什么.

您可以使用普通的基于 xml 的应用程序上下文并在其中配置您的注释扫描,或者您可以创建一个自定义的 fatory bean 来创建注释应用程序上下文.这将指定父引用,然后进行扫描.

看看源码...

工厂看起来像这样:

公共类 AnnotationContextFactory 实现 FactoryBean{私有 String[] 包;私有 ApplicationContext 父级;@覆盖公共 ApplicationContext getObject() 抛出异常 {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();上下文.setParent(父);上下文.扫描(包);上下文.刷新();返回上下文;}@覆盖公共类获取对象类型(){返回 ApplicationContext.class;}@覆盖公共布尔 isSingleton() {返回真;}public void setPackages(String... args) {this.packages = args;}public void setParent(ApplicationContext parent) {this.parent = 父母;}}

还有你的 bean 定义:

<property name="parent" ref="moduleA_ApplicationContext"/><属性名称=包"><列表><value>za.co.test2</value></list></属性></bean>

I'm facing an issue trying to define a context hierarchy using AnnotationConfigApplicationContext.

The problem is when defining a module context inside beanRefContext.xml and setting the 'parent' property with another context (XML/Annotated based).

Example:

beanRefContext.xml in module A

<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>

beanRefContext.xml in module B

<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
}

Module B application context fails to find bean defined in module A application context.
From looking at the code of AnnotationConfigApplicationContext it seems that the scanning process doesn't use the parent as a reference to resolve beans.

Is there something I'm doing wrong or my attempt to create a hierarchy is impossible with annotation configuration?

解决方案

The problem stems from the fact that the constructor of the AnnotationConfigApplicationContext does the scan. Thus the parent is not set at this stage, it is only set after the scan is done as the parent is set by a property - thus the reason why it does not find your bean.

The default AnnotationConfigApplicationContext bean does not have a constructor that takes a parent factory - not sure why.

You can either use the normal xml based application context and configure your annotation scanning in there or you can create a custom fatory bean that will do create the annotation application context. This would specify the parent reference and then do the scan.

Take a look at the source...

The factory would look like this:

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;
    }
}

And your bean definition:

<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>

这篇关于AnnotationConfigApplicationContext 和父上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆