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

目录
  • 一、实现了Aware的接口
  • 二、为什么要使用 Aware 接口
  • 三、Aware接口执行顺序

一、实现了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接口实现及执行顺序详解的详细内容,更多关于Spring Aware接口执行顺序的资料请关注我们其它相关文章!

(0)

相关推荐

  • SpringBoot ApplicationContextAware拓展接口使用详解

    近日沉醉于熟悉公司新项目的过程,不断地接触新的应用场景与实现技术,对于我是一种学不来的进步,实践是检验真理的唯一标准.我们今天就浅浅的谈一谈springboot提供的16个拓展接口之一的ApplicationContextAware接口的应用场景与实际作用! ApplicationContextAware接口: public interface ApplicationContextAware extends Aware { void setApplicationContext(Applicati

  • 详解spring中的Aware接口功能

    目录 一,ApplicationContextAware 二.ApplicationEventPublisherAware 在spring中有很多以XXXAware命名的接口,很多人也不清楚这些接口都是做什么用的,这篇文章将描述常用的一些接口. 一,ApplicationContextAware 获取spring容器,用来访问容器中定义的其他bean.实现接口方法public void setApplicationContext(ApplicationContext applicationCon

  • Spring的Aware接口你知道多少

    若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖.所以通过让bean 实现 Aware 接口,则能在 bean 中获得相应的 Spring 容器资源. Spring 中提供的 Aware 接口有: BeanNameAware:注入当前 bean 对应 beanName BeanClassLoaderAware:注入加载当前 bean 的 ClassLoader BeanFactoryAware:注入 当前BeanFactory容器 的引用 BeanNameAw

  • 探究实现Aware接口的原理及使用

    目录 前言 设计&实现 Aware 感知接口 提供具体能力的接口 测试 前言 spring 对bean的创建过程做了很完整的封装.但是提供了非常多的扩展接口,供我们使用.这一节主要是实现spring提供的获取 beanFactory,classLoader 等属性的能力. 在我们开发过程中我们经常会使用到 ApplicationContextAware接口,来获取到 spring的上下文.来完成对bean的获取,当拿到了BeanFactory以后,我们能做的东西就多起来了,我们可以通过的spri

  • Spring中的aware接口详情

    Spring中有很多继承于aware中的接口,这些接口到底是做什么用到的. aware,翻译过来是知道的,已感知的,意识到的,所以这些接口从字面意思应该是能感知到所有Aware前面的含义. 先举个BeanNameAware的例子,实现BeanNameAware接口,可以让该Bean感知到自身的BeanName(对应Spring容器的BeanId属性)属性,举个例子: BeanNameAware接口的定义: public interface BeanNameAware extends Aware

  • Java中EnvironmentAware 接口的作用

    目录 研究背景 源码介绍以及使用方法 作用 使用方式代码示例 总结 研究背景 我們在搞新的配置中心Nacos的時候,为了获取新的配置中心的配置文件中配置的 dataId,以及配置 serverAddr.nacosGroup 等信息,所以才研究 EnvironmentAware 接口的如果写死话那岂不是太不像话了,那就太多的魔法值了,所以我们可以通过 environmentAware 这个接口进行从配置文件中[application.properties]获取配置的配置中心的信息详情 nacos.

  • 对for循环中表达式和循环体的执行顺序详解

    对于学c的朋友来说,for循环可能使我们经常用到的一种循环语句 for(表达式1:表达式2:表达式3){循环体} 知道其的语句执行顺序对我们来说可以避免很多失误 我们可以利用下面这个小程序轻易测出其内在的语句循环顺序: #include<stdio.h> void main() { int i; for (printf("#1\n"),i=1; printf("#2\n"),i<=5; printf("#3\n"),i++) {

  • vue中各选项及钩子函数执行顺序详解

    在vue中,实例选项和钩子函数和{{}}表达式都是不需要手动调用就可以直接执行的. vue的生命周期如下图: 在页面首次加载执行顺序有如下: beforeCreate //在实例初始化之后.创建之前执行 created //实例创建后执行 beforeMounted //在挂载开始之前调用 filters //挂载前加载过滤器 computed //计算属性 directives-bind //只调用一次,在指令第一次绑定到元素时调用 directives-inserted //被绑定元素插入父

  • 基于Laravel 多个中间件的执行顺序详解

    问题 一个路由需要用到多个中间件,其中一个是 Laravel 自带的 auth 中间件. 发现这个中间件不管放在哪里,总是在自定义中间件之前执行. 如果业务需要自定义中间在 auth 之前执行,还是有办法的. 解决方案 观察定义中间件的 app\Http\Kernel 类,是继承的 Illuminate\Foundation\Http\Kernel 类. 再打开 Illuminate\Foundation\Http\Kernel ,发现有这样一个数组 ... /** * The priority

  • 对python中的try、except、finally 执行顺序详解

    如下所示: def test1(): try: print('to do stuff') raise Exception('hehe') print('to return in try') return 'try' except Exception: print('process except') print('to return in except') return 'except' finally: print('to return in finally') return 'finally'

  • java异常处理执行顺序详解try catch finally

    目录 不含return的执行顺序 finally子句 含return的执行顺序 返回类型是对象类型时值的变化 结论 不含return的执行顺序 执行顺序为执行try中代码,如果没有异常,然后执行try catch后续的代码.如: public static void main(String[] args) { try { int j = 10 / 2; System.out.println("执行try中代码!"); } catch (Exception e) { e.printSta

  • Mysql系列SQL查询语句书写顺序及执行顺序详解

    目录 1.一个完整SQL查询语句的书写顺序 2.一个完整的SQL语句执行顺序 3.关于select和having执行顺序谁前谁后的说明 1.一个完整SQL查询语句的书写顺序 -- "mysql语句编写顺序" 1 select distinct * 2 from 表(或结果集) 3 where - 4 group by -having- 5 order by - 6 limit start,count -- 注:1.2属于最基本语句,必须含有. -- 注:1.2可以与3.4.5.6中任一

  • Spring Security实现接口放通的方法详解

    目录 1.SpringBoot版本 2.实现思路 3.实现过程 3.1新建注解 3.2新建请求枚举类 3.3判断Controller方法上是否存在该注解 3.4在SecurityConfig上进行策略的配置 3.5在Controller方法上应用 3.6效果展示 在用Spring Security项目开发中,有时候需要放通某一个接口时,我们需要在配置中把接口地址配置上,这样做有时候显得麻烦,而且不够优雅.我们能不能通过一个注解的方式,在需要放通的接口上加上该注解,这样接口就能放通了.答案肯定是可

  • vue中created、watch和computed的执行顺序详解

    目录 前言 为什么? 1.关于initComputed 2.关于initWatch 总结 前言 面试题:vue中created.watch(immediate: true)和computed的执行顺序是啥? 先看个简单的例子: // main.js import Vue from "vue"; new Vue({ el: "#app", template: `<div> <div>{{computedCount}}</div> &

  • Spring Aop常见注解与执行顺序详解

    目录 Spring Aop 的常用注解 常见问题 示例代码 配置文件 接口类 实现类 aop 拦截器 测试类 执行结论 多切面的情况 代理失效场景 总结 Spring 一开始最强大的就是 IOC / AOP 两大核心功能,我们今天一起来学习一下 Spring AOP 常见注解和执行顺序. Spring Aop 的常用注解 首先我们一起来回顾一下 Spring Aop 中常用的几个注解: @Before 前置通知:目标方法之前执行 @After 后置通知:目标方法之后执行(始终执行) @After

  • springboot Junit 执行顺序详解

    目录 springboot Junit 执行顺序 SpringBoot JUnit 测试 Controller springboot Junit 执行顺序 我们在写JUnit测试用例时,有时候需要按照定义顺序执行我们的单元测试方法,比如如在测试数据库相关的用例时候要按照测试插入.查询.删除的顺序测试. 如果不按照这个顺序测试可能会出现问题,比如删除方法在前面执行,后面的方法就都不能通过测试,因为数据已经被清空了.而JUnit测试时默认的顺序是随机的. 所以这时就需要有办法要求JUnit在执行测试

随机推荐