关于spring中environment注入为null的一点理解
最近在学习spring的源码 ,在学习中经常出现一件事,就是自动注入的某些属性不知道忘了那些配置经常会出现null的现象,现在做一些统一整理:
首先:spring中的bean从注入方式上会分成三种,一种是普通的javaBean,就是自己在配置文件中写好的放在容器中的,在一种就是系统环境bean,包括三个,Environment,SystemPropertits,SystemEnvironment,还有一种是实现了XXXAware接口的bean,
第一种不解释
第二种,这种bean不是我们自己创建的,而是spring帮我们自动创建的,spring代码如下:
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
儿上面的getEnvironment()方法的代码如下:
public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); }
默认会返回一个Environment接口的实现StandardEnvironment;用来存贮我们所需要的属性;
第三种,实现XXXAware接口的类
代码如下:
private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware)bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware)bean).setBeanFactory(this); } } }
這是系統默认的几个Aware,其他的Aware实现与之类似,具体使用方法如下:
public class Student implements EnvironmentAware { Environment environment; private int id; public Student(int id) { this.id=id; } @Override public void setEnvironment(Environment environment) { this.environment=environment; } }
测试代码
public class Main { public static void main (String[] args){ ApplicationContext context=new ClassPathXmlApplicationContext("classpath:resources\\META-INF\\spring\\camel-context.xml"); System.out.println(((Student)context.getBean("xiaoming")).environment==null); } }
结果:
原理就是使用了个回调方法,也没啥说的
这三种方式,在不显式声明使用自动注入的情况下,第一种与第二种将不会注入到自己创建的javaBean之中,在开启自动注入的情况下,也就是说在配置文件中添加
component-scan
子元素,前两种的属性将会注入到所创建的javaBean之中;
总结,当所创建的javaBean之中属性出现null时,考虑如下解决方式:
1.仔细查看配置文件与配置类,是否声明了相关的类型,且
constructor-arg
property 等配置文件的相关子元素是否配置得当
IDEA编译器为spring提供了相当强的插件支持,建议换个编译器~~~~
2.若是属性在配置文件或者配置类里面已经声明且符合唯一约束;
3.若是使用了@Autowire等相关注解,查看是否开启了自动注解,开启自动注解方法是;在相关的配置文件或者配置类里面声明
<context:component-scan/>
或者是
@ComponentScan 注解
4。此时会解决绝大部分null问题,当仍为null,考虑实现相关的Aware接口,比如ApplicationContextAware,此时他会将ApplicationContext注入到你的javaBean中,而一般情况下他不会给你自动注入的;
阅读更多- 关于spring依赖注入到普通类中为null的情况解决理解方案
- 关于Spring的控制反转、依赖注入等的理解
- 一点关于spring依赖注入的代码
- 关于Jersey整合Spring注入出现NullPointException问题
- 关于Spring IOC的一点个人理解
- 关于spring切面的一点理解,记录一下
- 关于Spring中的[控制反转]和[依赖注入]的深入理解
- 关于Provider Bridge的一点理解
- 关于单例的一点自我理解
- 安卓开发 第一篇 关于依赖注入框架dagger2的使用和理解
- [小技巧]关于spring boot 整合mybatis-plus: value为null时不返回的问题。
- 关于特性和类的一点理解
- 关于Spring JPA的一点小总结
- 关于Hrris角点检测的一点理解
- 关于Spring父子容器的理解
- 关于进程的一点理解
- 关于Provider Bridge的一点理解
- 关于怎么解决从ajax传入的json参数注入到Controller的接收对象 以及如何在Spring Boot项目使用参数校验
- 关于Spring Boot 的一些简单理解和应用
- Oracle - 关于恢复数据库的一点理解