autowired的对象为null_Spring-framework @Autowired注入bean 为null之谜

本文探讨了在Spring框架中,@Autowired注解的对象为null的问题。通过检查bean定义和运行代码,发现由于使用new关键字创建App实例导致依赖注入失效。解决方案是通过Spring容器获取App实例,确保所有bean都在Spring的管理之下。
摘要由CSDN通过智能技术生成

环境:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值