环境:
JDK1.8
Spring-framework4.1.2.RELEASE
如下图所示的一个Spring javaSE工程
applicationContext.xml内容如下:
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">
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的实例;