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的实例;