您的位置:首页 > 编程语言 > Java开发

关于spring中environment注入为null的一点理解

2018-07-31 19:15 190 查看

最近在学习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中,而一般情况下他不会给你自动注入的;

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: