java 注入为空_Spring-framework @Autowired注入bean 为null之谜

环境:

JDK1.8

Spring-framework4.1.2.RELEASE

如下图所示的一个Spring javaSE工程

3c02419cafeeec14c461310e7032a62d.png

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();

}

}

输出结果:

0a7a36a079ff03b8ba93f051e0d8a72b.png

总结:

输出正常. 这也就说明了,spring在管理bean注入的策略是这样的:

当A组件依赖B, 要想使用spring依赖注入得到组件B的实例, 那么A本身也要是通过Spring的bean来创建的才行. 而不是直接new出A的实例;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 当使用@Autowired注入的对象为空时,可能有几种情况。首先,检查被@Autowired注解的对象是否已经被注入Spring容器中了。确保使用@Autowired注解的对象也已存在Spring的容器中。其次,如果对象使用了new关键字进行实例化,那么它并没有被交给Spring管理,因此@Autowired注入的对象会为空。在这种情况下,可以手动获取Spring容器中的Bean实例。可以通过实现ApplicationContextAware接口来获取ApplicationContext对象,并使用该对象来手动获取需要注入Bean实例。可以参考以下代码示例: ```java import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class BeanUtils implements ApplicationContextAware { protected static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { if (applicationContext == null) { applicationContext = arg0; } } public static Object getBean(String name) { // name表示其他要注入的注解name名 return applicationContext.getBean(name); } /** * 拿到ApplicationContext对象实例后就可以手动获取Bean的注入实例对象 */ public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } } ``` 通过使用BeanUtils类中的getBean方法,可以手动获取需要注入Bean实例。请确保在使用之前,已经正确配置了Spring容器和相关的Bean。 #### 引用[.reference_title] - *1* [@Autowired 注入bean是null](https://blog.csdn.net/qq_44885775/article/details/124877637)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [使用@Autowired注解获取对象为null的几种情况](https://blog.csdn.net/sunao1106/article/details/126752663)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [@Autowired 注入null 的原因与解决方式](https://blog.csdn.net/weixin_42826932/article/details/128559132)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值