码迷,mamicode.com
首页 > 编程语言 > 详细

Spring Aware原理

时间:2020-02-29 22:23:41      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:except   bsp   信息   mic   contex   end   使用   引入   alt   

上一篇中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的方法

技术图片

 

 

3、进入postProcessBeforeInitialization方法

技术图片

 

 

 

4、进入ApplicationContextAwareProcessor类的invokeAwareInterfaces方法

技术图片

 

 

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

技术图片

 

 这就是通过启动类加载器,实现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原理

标签:except   bsp   信息   mic   contex   end   使用   引入   alt   

原文地址:https://www.cnblogs.com/linlf03/p/12384829.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!