环境:
JDK1.8
Spring-framework4.1.2.RELEASE
如下图所示的一个Spring javaSE工程
applicationContext.xml内容如下:
<?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>
TestInterface2内容:
package com.chenjun.learnspring.annotation; public interface TestInterface2 { public void print(); }
TestInterfaceImpl2内容:
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"); } }
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 = new App(); app.proxyPrint(); } public void proxyPrint() { testInterface2.print(); } }
编译运行App.class主类
输出结果发现空指针异常,也就是说testInterface2的实现类并没有注入进来
Exception in thread "main" java.lang.NullPointerException
at com.chenjun.learnspring.annotation.App.proxyPrint(App.java:24)
at com.chenjun.learnspring.annotation.App.main(App.java:20)
这是怎么回事呢,是因为testInterfaceImpl2这个类没有被Spring容器所管理吗?
我打算输出一下Spring容器里面的bean一看究竟:
于是我编写如下代码:
略微修改之后的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"); 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的实例;