Spring的Aware接口实现及执行顺序详解

作者:刨红薯的小羊竿尔 时间:2023-03-09 09:50:53 

一、实现了Aware的接口

Spring中有很多继承于aware中的接口,这些接口到底是做什么用到的,下面我们就一起来看看吧。

Aware 接口用于注入一些与容器相关信息,例如:

EnvironmentAware:实现EnvironmentAware接口重写setEnvironment方法后,可以获得配置文件属性值

BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader

BeanNameAware: 注入当前 bean 对应 beanName

BeanFactoryAware: 注入 当前BeanFactory容器 的引用

ApplicationContextAware: 获取容器本身ApplicationContext对象,可以在bean中得到bean所在的应用上下文

EmbeddedValueResolverAware:获取properties文件单个属性值,一般使用@Value属性值;EmbeddedValueResolverAware是另一种基于Spring解析获取 properties 文件单个属性值的方式

ApplicationEventPublisherAware:事件发布器的接口,使用这个接口,我们自己的bean就拥有了发布事件的能力。

ResourceLoaderAware:获取ResourceLoader实例,获取资源加载器读取资源文件

二、为什么要使用 Aware 接口

Aware接口是回调, * 和观察者设计模式的混合,一般指具备由Spring 容器通过Aware回调方法通知的特定的bean对象,简单来说就是可以通过实现该接口拿到Spring容器内部的一些资源。实际的回调方法由各个子接口确定,通常应仅包含一个接受单个参数、返回 void 的方法;但是一般情况下,Spring不建议使用该接口,因为使用这种方式会将业务代码与Spring 耦合,有所违背IOC 原则。

1、BeanNameAware

public class MyBeanName implements BeanNameAware {
   @Override
   public void setBeanName(String beanName) {
       System.out.println(beanName);
   }
}

2、BeanFactoryAware

public class MyBeanFactory implements BeanFactoryAware {
   private BeanFactory beanFactory;
   @Override
   public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
       this.beanFactory = beanFactory;
   }
   public void getMyBeanName() {
       MyBeanName myBeanName = beanFactory.getBean(MyBeanName.class);
       System.out.println(beanFactory.isSingleton("myCustomBeanName"));
   }
}

3、EnvironmentAware

@Configuration
public class MyBatisConfig implements EnvironmentAware {
   private static Environment environment;
   @Override
   public void setEnvironment(Environment environment) {
       this.environment = environment;
   }
   @Bean
   public DataSource druidDataSource() throws Exception {
       Properties props = new Properties();
       props.put("driverClassName", environment.getProperty("datasource.driverClassName"));
       props.put("url", environment.getProperty("datasource.url"));
       props.put("username", environment.getProperty("datasource.username"));
       props.put("password", environment.getProperty("datasource.password"));
       return DruidDataSourceFactory.createDataSource(props);
   }
}  

4、EmbeddedValueResolverAware

@Component
public class PropertiesUtil implements EmbeddedValueResolverAware {
   private StringValueResolver resolver;
   @Override
   public void setEmbeddedValueResolver(StringValueResolver resolver) {
       this.resolver = resolver;
   }
   /**
    * 获取属性,直接传入属性名称即可
    * @param key
    * @return
    */
   public String getPropertiesValue(String key) {
       StringBuilder name = new StringBuilder("${").append(key).append("}");
       return resolver.resolveStringValue(name);
   }
}
public class MyBean implements BeanNameAware, ApplicationContextAware, InitializingBean {
   private static final Logger log = LoggerFactory.getLogger(MyBean.class);
   @Override
   public void setBeanName(String name) {
       log.debug("当前bean " + this + " 名字叫:" + name);
   }
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       log.debug("当前bean " + this + " 容器是:" + applicationContext);
   }
   @Override
   public void afterPropertiesSet() throws Exception {
       log.debug("当前bean " + this + " 初始化");
   }
}

三、Aware接口执行顺序

定义类SimpleAware实现了部分Aware的接口的自定义bean,经过程序运行测试其执行顺序如下:

@Component
public class SimpleAware implements
       ApplicationContextAware,
       ApplicationEventPublisherAware,
       BeanClassLoaderAware,
       BeanFactoryAware,
       BeanNameAware,
       ResourceLoaderAware {
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       System.out.println("ApplicationContextAware 回调");
   }
   @Override
   public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
       System.out.println("ApplicationEventPublisherAware 回调");
   }
   @Override
   public void setBeanClassLoader(ClassLoader classLoader) {
       System.out.println("BeanClassLoaderAware 回调");
   }
   @Override
   public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
       System.out.println("BeanFactoryAware 回调");
   }
   @Override
   public void setBeanName(String name) {
       System.out.println("BeanNameAware 回调");
   }
   @Override
   public void setResourceLoader(ResourceLoader resourceLoader) {
       System.out.println("ResourceLoaderAware 回调");
   }
}

按照以下顺序执行:

BeanNameAware-->BeanClassLoaderAware-->BeanFactoryAware-->ResourceLoaderAware-->ApplicationEventPublisherAware-->ApplicationContextAware

Spring的Aware接口实现及执行顺序详解

来源:https://juejin.cn/post/7180341492030898231

标签:Spring,Aware,接口,执行顺序
0
投稿

猜你喜欢

  • Java并发编程之浅谈ReentrantLock

    2022-08-25 10:46:02
  • C#中面向对象编程机制之继承学习笔记

    2023-12-12 03:46:43
  • Spring Cloud基于zuul实现网关过程解析

    2021-09-11 06:52:19
  • java后台批量下载文件并压缩成zip下载的方法

    2021-07-24 21:13:11
  • Spring Boot集成教程之异步调用Async

    2023-03-10 03:39:50
  • C#实现飞行棋(Winform)

    2023-08-07 07:08:55
  • java的IO流详细解读

    2022-01-24 20:18:40
  • Android自定义EditText右侧带图片控件

    2023-08-30 03:09:47
  • spring cloud Ribbon用法及原理解析

    2021-11-28 15:27:21
  • C# 常用协议实现模版及FixedSizeReceiveFilter示例(SuperSocket入门)

    2023-12-12 04:17:48
  • spring AOP的Around增强实现方法分析

    2021-10-03 06:22:39
  • 使用MAT进行JVM内存分析实例

    2023-12-14 05:29:51
  • C#引用类型转换的常见方式总结

    2022-03-02 16:53:58
  • Java并发编程之闭锁与栅栏的实现

    2022-01-09 15:00:12
  • C#中使用资源的方法分析

    2022-01-16 16:27:02
  • Android实现退出界面弹出提示对话框

    2023-03-09 12:19:44
  • Android使用Service实现简单音乐播放实例

    2023-11-30 20:03:23
  • c#中oracle的to_date函数使用方法

    2021-09-06 10:21:17
  • C#获取本机IP地址(ipv4)

    2021-08-29 19:22:06
  • 详谈Java几种线程池类型介绍及使用方法

    2023-10-13 03:27:30
  • asp之家 软件编程 m.aspxhome.com