Announcement Announcement Module
Collapse
No announcement yet.
Bug or Feature at Autowiring? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bug or Feature at Autowiring?

    Hello, I got an issue about @Autwired annotation on a Bean that is accessed through a parent application context.
    There are two application contexts: Parent and Child. Parent context contains bean B and child context contains bean A. A uses @Autowired on a class variable B. It looks like this:

    Code:
    class A {
        @Autowired
        private B myB;
    
        public B getMyB() {
            return myB;
        }
    }
    
    class B {}
    As I get bean A from child context the @Autowiring on myB didnt work. MyB reference is null. The following testcase shows how it is working:


    Code:
        public void testParentAutowiring() {
    
            // arrange
    
            // Parent
            GenericXmlApplicationContext ctxParent = new GenericXmlApplicationContext();
            BeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(B.class).getBeanDefinition();
            ctxParent.registerBeanDefinition(B.class.getName(), bd);
    
            // Child
            GenericXmlApplicationContext ctxChild = new GenericXmlApplicationContext();
            ctxChild.setParent(ctxParent);
            BeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(A.class).getBeanDefinition();
            ctxChild.registerBeanDefinition(A.class.getName(), bd2);
    
            // act
            A a = ctxChild.getBean(A.class);
            B b = ctxChild.getBean(B.class);
    
            // assert
            assertNotNull(a);
            assertNotNull(b);
            assertEquals(null, a.getMyB());
        }
    It seems that it is legit to load beans that are registered in a parent context through child contexts by calling getBean Method but not inject them through @Autowiring. Is that a bug, works as designed or am I doing something wrong?

    Thanks in advance.

  • #2
    It neither a bug nor a feature, it works as designed... Your code is just wrong...

    You are using a GenericXmlApplicationContext, that expects XML for expressing dependencies, you are using annotations annotations != xml... Also you are only registering definitions, you should first refresh the contexts. Finally if you want to annotations to work before adding bean definitions register a AutowiredAnnotationBeanPostProcessor.

    Comment


    • #3
      Thanks Marten, works perfectly fine now:

      Code:
          @Test
          public void testParentAutowiring() {
      
              // arrange
      
              // Parent
              GenericXmlApplicationContext ctxParent = new GenericXmlApplicationContext();
              BeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(B.class).getBeanDefinition();
              ctxParent.registerBeanDefinition(B.class.getName(), bd);
      
              // Child
              GenericXmlApplicationContext ctxChild = new GenericXmlApplicationContext();
              ctxChild.setParent(ctxParent);
      
              AutowiredAnnotationBeanPostProcessor abpp = new AutowiredAnnotationBeanPostProcessor();
              abpp.setBeanFactory(ctxChild.getBeanFactory());
              ctxChild.getBeanFactory().addBeanPostProcessor(abpp);
      
              BeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(A.class).getBeanDefinition();
              ctxChild.registerBeanDefinition(A.class.getName(), bd2);
      
              ctxParent.refresh();
              ctxChild.refresh();
      
              // act
              A a = ctxChild.getBean(A.class);
              B b = ctxChild.getBean(B.class);
      
              // assert
              assertNotNull(a);
              assertNotNull(b);
              assertNotNull(a.getMyB());
          }

      Comment

      Working...
      X