Research on automatic injection failure in spring configuration file when directly defining beans

Source: Internet
Author: User

A spring injection problem, first look at an ordinary spring Bean,

public class Foo {@AutowiredBar bar;public void dosomething () {bar.dosomething ();}}

Spring Configuration One:

<bean id= "Bar" class= "Com.test.Bar" ></bean><bean id= "foo" class= "Com.test.Foo" ></bean>

Unit tests:

@Testpublic void Test_dosomthing () {ApplicationContext ctx = new Classpathxmlapplicationcontext (" Applicationcontext-test.xml "); Foo foo = Ctx.getbean (Foo.class); foo.dosomething ();}

Execute the above test method, error

Java.lang.NullPointerExceptionat com.test.Foo.doSomething (foo.java:15) at com.test.FooTest.test_doSomthing ( FOOTEST.JAVA:13)

The bar in the Foo Bean is not injected.

Spring Configuration II:

<context:component-scan base-package= "Com.test" ></context:component-scan>

The above-mentioned unit test method can be successfully implemented when the configuration is changed to two. After analyzing the log and viewing the source code, it was found that 6 beans were loaded with configuration two o'clock, as follows:

DEBUG Org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions ( abstractbeandefinitionreader.java:216) Loaded 6 bean Definitions from location pattern [Applicationcontext-test.xml] DEBUG Org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory ( abstractapplicationcontext.java:530) Bean Factory for Org[email protected]3c4e80d3:org.s[email Protected]14cc51c8: defining Beans [Bar,foo,org.springframework.context.annotation.internalconfigurationannotationprocessor, Org.springframework.context.annotation.internalAutowiredAnnotationProcessor, Org.springframework.context.annotation.internalRequiredAnnotationProcessor, Org.springframework.context.annotation.internalCommonAnnotationProcessor]; Root of Factory hierarchy

Instead, use the configuration for only two beans at a moment, as follows:

DEBUG Org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions ( abstractbeandefinitionreader.java:216) Loaded 2 bean definitions from location pattern [Applicationcontext-test.xml] DEBUG Org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory ( abstractapplicationcontext.java:530) Bean Factory for Org[email protected]45ebbb93:org.s[email protected]18481697: defining beans [Bar,foo]; Root of Factory hierarchy

The reason for the configuration of the two execution unit tests seems to be the extra beans. Is it that as long as there are context:component-scan elements in the automatic there will be a few beans generated? Verify this hypothesis

Add a context:component-scan element that is not actually meaningful in configuration one, as follows:

<context:component-scan base-package= "Com.nonexist" ></context:component-scan>

At this point, the execution unit test can pass, same as configuration two will also load 6 beans. So which of the 6 beans actually played a role in injecting bar to Foo?

The breakpoint debugging found that the Autowiredannotationbeanpostprocessor Bean has played a role, see output log:

2015-04-25 20:23:09 debug org.springframework.beans.factory.annotation.injectionmetadata.< Init> (injectionmetadata.java:60)   found injected element on class [ com.test.foo]: autowiredfieldelement for com.test.bar com.test.foo.bar2015-04-25  20:23:09 debug org.springframework.beans.factory.annotation.injectionmetadata.inject ( injectionmetadata.java:85)   Processing injected method of bean  ' foo ':  Autowiredfieldelement for com.test.bar com.test.foo.bar2015-04-25 20:23:09 debug  org.springframework.beans.factory.support.abstractbeanfactory.dogetbean (AbstractBeanFactory.java:245)   Returning cached instance of singleton bean  ' Bar ' 2015-04-25  20:23:09 debug  Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.registerDependentBeans ( Autowiredannotationbeanpostprocessor.java:424)   Autowiring by type from bean name  ' foo '  to  bean named  ' Bar ' 2015-04-25 20:23:09 debug  Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean ( abstractautowirecapablebeanfactory.java:458)   finished creating instance of bean   ' foo '

So directly in the configuration of an explicit add autowiredannotationbeanpostprocessor bean? As shown below:

<bean id= "Bar" class= "Com.tcl.account.service.test.Bar" ></bean><bean id= "foo" class= " Com.tcl.account.service.test.Foo "></bean><bean id=" Autowiredannotationbeanpostprocessor "class=" Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor "></bean>

Will the test pass? Will pass. See log:

Debug org.springframework.beans.factory.support.abstractbeandefinitionreader.loadbeandefinitions ( abstractbeandefinitionreader.java:216)   Loaded 3 bean definitions from  location pattern [applicationcontext-test.xml]debug  Org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory ( abstractapplicationcontext.java:530)   bean factory for org[email protected] 7767d3c1: org.s[email protected]1924ed52: defining beans [bar,foo, autowiredannotationbeanpostprocessor]; root of factory hierarchydebug  Org.springframework.beans.factory.annotation.injectionmetadata.<init> (InjectionMetadata.java:60)    found injected element on class [com.test.foo]: autowiredfieldelement  for com.test.Bar com.test.Foo.barDEBUG  Org.springframework.beans.factory.annotation.InjectionMetadata.inject (INJECtionmetadata.java:85)   Processing injected method of bean  ' foo ':  autowiredfieldelement for com.test.bar com.test.foo.bardebug  Org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean (abstractbeanfactory.java:245)    Returning cached instance of singleton bean  ' Bar ' debug  Org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.registerDependentBeans ( autowiredannotationbeanpostprocessor.java:424)   autowiring by type from bean  name  ' foo '  to bean named  ' bar ' debug  Org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean ( abstractautowirecapablebeanfactory.java:458)   finished creating instance of bean   ' foo '

So why does adding the Context:componet-scan element in the config file automatically add the other 4 beans? A breakpoint debug found that spring implicitly loaded 4 beans were loaded in the following way:

Set<beandefinitionholder> Org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors ( Beandefinitionregistry registry, Object Source)

Its invocation chain is as follows:




Research on automatic injection failure in spring configuration file when directly defining beans

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.