Spring Aware原理

上一篇中Spring Boot 属性配置中的启动类加载器有实现EnvironmentAware接口,这里我们就介绍下Spring Aware

一、Aware介绍

Spring框架有点: Bean感知不到容器的存在

使用场景: 需要使用Spirng容器的功能资源

引入缺点: Bean和容器强耦合

二、常用Aware

类名作用
BeanNameAware获取容器中bean名称
BeanClassLoaderAware获得类加载器
BeanFactoryAware获得bean创建工厂
EnviromentAware获得环境变量
EnvironmentValueResolverAware获取spring容器加载的properties文件属性值
ResourceLoaderAware获得资源加载器
ApplicationEventPublisherAware  获得应用程序发布器
MessageSourceAware获得文本信息
ApplicationContextAware  获得当前应用上下文
三、Aware调用原理我们以ResultCommandLineRunner启动类加载器为例。实现了EnvironmentAware接口,目的就是为了获得environment,从而打印属性
@Component
public class ResultCommandLineRunner implements CommandLineRunner, EnvironmentAware , MyAware{

    private Environment env;

    private  Flag flag;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(flag.isCanOperate());
        System.out.println(env.getProperty("weburl"));
        System.out.println(env.getProperty("weburl.random"));
        System.out.println(env.getProperty("weburl.vm.name"));
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.env = environment;
    }

    @Override
    public void setFlag(Flag flag) {
        this.flag = flag;
    }
}

  

1、Debug运行程序,定位到initializeBean方法

2、进入initializeBean。beanName为resultCommandLineRunner(可以根据beanName设置条件断点)

下面是initializeBean的方法

Spring Aware原理

3、进入postProcessBeforeInitialization方法

Spring Aware原理

4、进入ApplicationContextAwareProcessor类的invokeAwareInterfaces方法

Spring Aware原理

5、然后就进入了setEnvironment方法,参数为environment。

Spring Aware原理

 这就是通过启动类加载器,实现EnvironmentAware,从而获得Environment的流程

 四、模拟创建自定义Aware

1、创建Flag类

@Component
public class Flag
{
    private boolean canOperate = true;

    public boolean isCanOperate() {
        return canOperate;
    }

    public void setCanOperate(boolean canOperate) {
        this.canOperate = canOperate;
    }
}

2、创建自定义Aware接口,目的就是为了获得Flag。继承Aware接口

public interface MyAware extends Aware{

    void setFlag(Flag flag);
}

3、创建处理器

@Component
public class MyAwareProcess implements BeanPostProcessor{

    private final ConfigurableApplicationContext configurableApplicationContext;

    public MyAwareProcess( ConfigurableApplicationContext configurableApplicationContext){
        this.configurableApplicationContext = configurableApplicationContext;
    }

    @Nullable
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof Aware){
            if(bean instanceof  MyAware){
                ((MyAware)bean).setFlag((Flag) configurableApplicationContext.getBean("flag"));
            }
        }
        return bean;
    }
}

4、启动类加载器增加flag变量

@Component
public class ResultCommandLineRunner implements CommandLineRunner, EnvironmentAware , MyAware{

    private Environment env;

    private  Flag flag;

    @Override
    public void run(String... args) throws Exception {
        System.out.println(flag.isCanOperate());
        System.out.println(env.getProperty("weburl"));
        System.out.println(env.getProperty("weburl.random"));
        System.out.println(env.getProperty("weburl.vm.name"));
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.env = environment;
    }

    @Override
    public void setFlag(Flag flag) {
        this.flag = flag;
    }
}

5、运行。输出flag为true

Spring Aware原理