Me estoy enfrentando un problema tratando de definir un contexto jerarquía utilizando AnnotationConfigApplicationContext.

El problema es cuando la definición de un módulo de contexto dentro de beanRefContext.xml y configuración de los ‘padres’ de la propiedad con otro contexto (XML/Anotados base).

Ejemplo:

beanRefContext.xml en el módulo Un

<bean id="moduleA_ApplicationContext" 
clase="org.springframework.contexto.apoyo.ClassPathXmlApplicationContext"> 
<propiedad nombre="configLocations"> 
<lista> 
<valor>classpath:db-contexto.xml</valor> 
</list> 
</propiedad> 
</bean> 

db-context.xml

<bean id="dataSource" 
clase="org.apache.commons.el dbcp.BasicDataSource" 
destruir-method="cerrar" 
p:driverClassName="org.h2.Controlador" 
p:url="jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODO=MySQL;TRACE_LEVEL_SYSTEM_OUT=2"/> 

<!-- Sesión de Hibernate Fábrica --> 
<bean name="sessionFactory" 
clase="org.springframework.orm.hibernate3.la anotación.AnnotationSessionFactoryBean"> 
<propiedad nombre="dataSource" ref="dataSource"/> 
<propiedad nombre="useTransactionAwareDataSource" value="true"/> 
<propiedad nombre="packagesToScan"> 
<lista> 
<valor>com.ejemplo.modelo</valor> 
</list> 
</propiedad> 
<propiedad nombre="hibernateProperties"> 
<!-- hibernate props --> 
</propiedad> 
</bean> 

beanRefContext.xml en el módulo B

<bean id="moduleB_ApplicationContext" 
clase="org.springframework.contexto.la anotación.AnnotationConfigApplicationContext" > 
<propiedad nombre="padre" ref="moduleA_ApplicationContext"/> 
<constructor-arg> 
<lista> 
<valor>com.ejemplo.dao</valor> 
</list> 
</constructor-arg> 
</bean> 

FooHibernateDao

clase FooHibernateDao implementa FooDao { 
@Autowired 
@Qualifier("sessionFactory") 
privado SessionFactory sessionsFactory; 

//Métodos CRUD 
} 

Módulo B en el contexto de aplicación no puede encontrar bean definido en el módulo de Un contexto de aplicación.

Mirando en el código de AnnotationConfigApplicationContext parece que el proceso de digitalización no utilice el padre como referencia para resolver los frijoles.

Hay algo que estoy haciendo mal o mi intento de crear una jerarquía, es imposible con la anotación de configuración?

  • Esto debería funcionar bien. Puede dar un ejemplo de un grano de definición que no se ha encontrado, y cómo el niño contexto está tratando de resolver?
  • db-context.xml ha datasource y sessionFactory configurado en él (XML sencillo bean de configuración), pero al intentar autowire en module_B contexto de la aplicación dice que no puede encontrar sessionsFactory para satisfacer dao dependencias.
  • Por favor, edita tu pregunta, que nos muestra los componentes relevantes. Su descripción está bien, pero hay algo acerca de los detalles que deja de funcionar.
  • He añadido los componentes, espero que ayude
InformationsquelleAutor Bivas | 2010-12-06

5 Comentarios

  1. 6

    El problema proviene del hecho de que el constructor de la AnnotationConfigApplicationContext hace la exploración. Así, el padre no está en esta etapa, se establece sólo después de la exploración se hace como el de los padres, se establece por una propiedad – así pues, la razón por la que no encuentra su frijol.

    El valor predeterminado AnnotationConfigApplicationContext bean no tiene un constructor que toma un padre de fábrica – no sé por qué.

    Puede utilizar la normal basado en xml, en el contexto de aplicación y configurar su anotación de digitalización en el que hay o puede crear uno personalizado fatory bean que va a hacer crear la anotación en el contexto de aplicación. Esto tendría que especificar el padre de referencia y, a continuación, hacer el examen.

    Echar un vistazo a la fuente…

    La fábrica tendría este aspecto:

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

    Y tu bean definición:

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

    No utilizar XML para el niño contexto.
    El uso de ctx.setParent, a continuación, ctx.registrarse. Como este:

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

    Me encuentro con el mismo problema,

    Otra posibilidad es ampliar AnnotationConfigApplicationContext y agregar sólo la necesaria constructor o construir el contexto de la programación, si se ejecuta el AnnotationConfigApplicationContext de java.

  4. 0

    Lo que yo hice fue lo siguiente:

    BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance("classpath:beanRefContext.xml");
    BeanFactoryReference parentContextRef = locator.useBeanFactory("ear.context");
    ApplicationContext parentContext = (ApplicationContext) parentContextRef.getFactory();
    childContext.setParent(parentContext);

    Y adivine qué, trabajado 🙂

    PS: Si alguien sabe cómo reemplazar el classpath:beanRefContext.xml con un @de Configuración de la clase, por favor háganoslo saber todos.

  5. 0

    Yo también se ejecutan en un problema similar y después de investigar un poco he encontrado el siguiente enfoque usando un constructor de AnnotationConfigApplicationContext que permite establecer una jerarquía entre los contextos

    DefaultListableBeanFactory lbf = new DefaultListableBeanFactory(parentContext);
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(lbf);
    context.register(annotatedClass1.class, annotatedClass2.class);
    context.refresh();

Dejar respuesta

Please enter your comment!
Please enter your name here