JDK1.8java
Spring-framework4.1.2.RELEASEspring
以下圖所示的一個Spring javaSE工程app
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.chenjun.learnspring.annotation" /> </beans>
package com.chenjun.learnspring.annotation; public interface TestInterface2 { public void print(); }
package com.chenjun.learnspring.annotation; import org.springframework.stereotype.Service; @Service public class TestInterfaceImpl2 implements TestInterface2 { public void print() { System.out.println("TestInterfaceImpl2 is print"); } }
package com.chenjun.learnspring.annotation; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; @Component public class App { @Autowired private TestInterface2 testInterface2; public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); App app = new App(); app.proxyPrint(); } public void proxyPrint() { testInterface2.print(); } }
編譯運行App.class主類ui
輸出結果發現空指針異常,也就是說testInterface2的實現類並無注入進來spa
Exception in thread "main" java.lang.NullPointerException指針
at com.chenjun.learnspring.annotation.App.proxyPrint(App.java:24)code
at com.chenjun.learnspring.annotation.App.main(App.java:20)component
這是怎麼回事呢,是由於testInterfaceImpl2這個類沒有被Spring容器所管理嗎? xml
我打算輸出一下Spring容器裏面的bean一看究竟:對象
因而我編寫以下代碼:
package com.chenjun.learnspring.annotation; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; @Component public class App { @Autowired private TestInterface2 testInterface2; public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); String[] beanArray = applicationContext.getBeanDefinitionNames(); for(String s : beanArray) { System.out.println(s); } App app = new App(); app.proxyPrint(); } public void proxyPrint() { testInterface2.print(); } }
我把Spring容器裏面如今的bean名稱都打印一下,以下:
testInterfaceImpl2 app org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor Exception in thread "main" java.lang.NullPointerException at com.chenjun.learnspring.annotation.App.proxyPrint(App.java:31) at com.chenjun.learnspring.annotation.App.main(App.java:27)
從上面控制檯輸出信息能夠看到,spring容器中確實已經有了testInterfaceImpl2,可是爲何上面聲明這個bean的時候他沒有注入呢?
緣由就在於這行
App app = new App();
這行代碼把App用new關鍵字進行建立對象,這就使得app依賴的其餘bean已經脫離了spring的依賴注入管理
找到緣由以後,最終我修改App.java的代碼以下:
package com.chenjun.learnspring.annotation; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.stereotype.Component; @Component public class App { @Autowired private TestInterface2 testInterface2; public static void main(String[] args) { ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); App app = applicationContext.getBean(com.chenjun.learnspring.annotation.App.class); app.proxyPrint(); } public void proxyPrint() { testInterface2.print(); } }
輸出正常. 這也就說明了,spring在管理bean注入的策略是這樣的:
當A組件依賴B, 要想使用spring依賴注入獲得組件B的實例, 那麼A自己也要是經過Spring的bean來建立的才行. 而不是直接new出A的實例;