一文看懂 Spring Aware 接口功能

 更新时间:2024年12月24日 12:03:13   作者:齐 飞  
Aware接口是一个空接口,可以理解为是一个标记接口,方便在一个统一的方法(AbstractAutowireCapableBeanFactory.invokeAwareMethods)中进行判断处理赋值,在子接口写出各自的set方法,这篇文章主要介绍了一文看懂 Spring Aware 接口功能,需要的朋友可以参考下

前言

有些情况下,当Bean需要实现某个功能时,需要借助于 Spring容器对象属性 才能实现。此时就需要让该Bean先获取Spring容器对象属性,然后借助于Spring容器对象属性实现该功能。

  • 为了让Bean获取它所在的Spring容器对象属性,可以让该Bean实现 如ApplicationContextAware接口。
  • 通过实现ApplicationContextAware接口并重写set方法,Spring容器会自动把上下文环境对象调用ApplicationContextAware接口中的setApplicationContext方法,然后就可以通过ApplicationContext对象得到Spring容器中的Bean。
  • 可以将Aware理解为属性注入,不过不同地方在于,只有实现了这个接口的bean,当spring容器初始化的时候才会自动的将ApplicationContext注入进来。

Aware

Aware接口是一个空接口,可以理解为是一个标记接口,方便在一个统一的方法(AbstractAutowireCapableBeanFactory.invokeAwareMethods)中进行判断处理赋值,在子接口写出各自的set方法。

**Aware接口方法的主要作用是让 Bean 能够获取 Spring 容器的相关资源和信息,以便在后续的初始化和业务逻辑中使用。**可以理解为之前的属性赋值是将我们自定义属性的值进行赋值,而使用Aware可以让我们拿到Spring容器内部的容器对象。

/*
 * A marker superinterface
 * 在该接口的注释中也解释了该接口是一个标记接口
 */
public interface Aware {
}

常见的 Aware 接口及功能

BeanNameAware接口

  • 当一个 Bean 实现了BeanNameAware接口时,它可以获取自己在 Spring 容器中的 Bean 名称。这个接口中只有一个方法setBeanName(String name),Spring 容器在创建 Bean 的过程中会调用这个方法,并将 Bean 的名称作为参数传递进去。

ApplicationContextAware接口

  • 实现这个接口的 Bean 可以获取 Spring 的应用上下文(ApplicationContext)对象。ApplicationContext是 Spring 容器的核心接口,它提供了对容器中所有 Bean 的访问权限,还包括获取资源、发布事件等多种功能。

BeanFactoryAware接口

  • 与ApplicationContextAware类似,实现BeanFactoryAware接口的 Bean 可以获取 Bean 工厂(BeanFactory)对象。BeanFactory是 Spring 容器中用于创建和管理 Bean 的基础接口,相对ApplicationContext来说更加轻量级。

ApplicationEventPublisherAware接口

  • 如果Bean需要发布应用事件,可以实现此接口。

ResourceLoaderAware接口

  • 如果Bean需要加载资源文件(如XML文件、属性文件等),可以实现此接口。

EnvironmentAware接口

  • 如果Bean需要访问环境特定的信息(如配置文件位置、激活的配置文件等),可以实现此接口。

MessageSourceAware接口

  • 如果Bean需要进行国际化处理,可以实现此接口以获取消息源。

代码示例

如:Bean 实现了 ApplicationContextAware 接口,此时Spring会通过 setApplicationContext() 给Bean中的ApplicationContext属性值赋值。

org.springframework.context.ApplicationContextAware

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

通过类实现ApplicationContextAware接口,并重写接口中的setApplicationContext()方法,则可以获取 Spring 的应用上下文ApplicationContext对象

public class SpringContextUtil implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

Aware 接口中set()的调用时机

在以上代码中setApplicationContext()方法是spring容器进行调用的,在invokeAwareMethods中统一调用。
当子实现类实现ApplicationContextAware接口后,当前类中重写setApplicationContext为接口中setApplicationContext方法。Spring会在执行invokeAwareMethods()时由容器进行赋值。

Spring源码中的具体实现如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

private void invokeAwareMethods(String beanName, Object bean) {
    //如果 bean 是 Aware 实例
    if (bean instanceof Aware) {
        //如果bean是BeanNameAware实例
       if (bean instanceof BeanNameAware) {
           //调用 bean 的setBeanName方法
          ((BeanNameAware) bean).setBeanName(beanName);
       }
       //如果bean是 BeanClassLoaderAware 实例
       if (bean instanceof BeanClassLoaderAware) {
           //获取此工厂的类加载器以加载Bean类(即使无法使用系统classLoader,也只能为null)
          ClassLoader bcl = getBeanClassLoader();
          if (bcl != null) {
              //调用 bean 的 setBeanClassLoader 方法
             ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
          }
       }
       //检查bean是否实现了BeanFactoryAware,如果是,则调用其setBeanFactory方法设置工厂实例。
       if (bean instanceof BeanFactoryAware) {
          ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
       }
    }
}

什么时候调用invokeAwareMethods方法

invokeAwareMethods()通常是在Spring容器初始化一个bean的过程中被调用的。

  • 具体来说,在bean被创建并配置完成后,但还未完全初始化之前(即在init-method或InitializingBean的afterPropertiesSet()方法调用之前),Spring框架会检查该bean是否实现了某些特定的接口,如BeanNameAware、BeanFactoryAware等,并相应地调用这些接口的方法来设置必要的属性。
  • 这个过程是Spring框架内部的一部分,用来确保bean能够获得一些关于自身或者Spring应用上下文的信息。
  • 例如,让bean知道自己的名字、所属的BeanFactory或者是类加载器等。这样可以在bean的生命周期早期给予bean更多的上下文信息。

到此这篇关于一文看懂 Spring Aware 接口的文章就介绍到这了,更多相关Spring Aware 接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中synchronized的几种使用方法

    Java中synchronized的几种使用方法

    本文主要介绍了Java中synchronized的几种使用方法,synchronized可用于修饰普通方法、静态方法和代码块,下面详细内容介绍,需要的小伙伴可以参考一下
    2022-05-05
  • Java多线程编程之ThreadLocal线程范围内的共享变量

    Java多线程编程之ThreadLocal线程范围内的共享变量

    这篇文章主要介绍了Java多线程编程之ThreadLocal线程范围内的共享变量,本文讲解了ThreadLocal的作用和目的、ThreadLocal的应用场景、ThreadLocal的使用实例等,需要的朋友可以参考下
    2015-05-05
  • 利用Java8 Optional如何避免空指针异常详解

    利用Java8 Optional如何避免空指针异常详解

    Optional可以让你的代码具有可读性,且会避免出现空指针异常。 下面这篇文章主要给大家介绍了关于利用Java8 Optional如何避免空指针异常的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2018-01-01
  • JDK8环境中使用struts2的步骤详解

    JDK8环境中使用struts2的步骤详解

    这篇文章主要给大家介绍了关于在JDK8环境中使用struts2的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • 一分钟了解Java中List集合与set集合的多种遍历方式

    一分钟了解Java中List集合与set集合的多种遍历方式

    这篇文章主要介绍了一分钟了解Java中List集合与set集合的多种遍历方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • java 工作流引擎设计实现解析流程定义文件

    java 工作流引擎设计实现解析流程定义文件

    这篇文章主要为大家介绍了java 工作流引擎设计与实现及流程定义文件解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • Spring Cloud 配置中心内容加密的配置方法

    Spring Cloud 配置中心内容加密的配置方法

    这篇文章主要介绍了Spring Cloud 配置中心内容加密的配置方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-06-06
  • 必须掌握的十个Lambda表达式简化代码提高生产力

    必须掌握的十个Lambda表达式简化代码提高生产力

    这篇文章主要为大家介绍了必须掌握的十个Lambda表达式来简化代码提高生产力,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • Struts中action线程安全问题解析

    Struts中action线程安全问题解析

    这篇文章主要介绍了Struts中action线程安全问题解析,涉及实例代码,还是挺不错的,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • SpringCloud微服务剔除下线功能实现原理分析

    SpringCloud微服务剔除下线功能实现原理分析

    SpringCloud是一种微服务的框架,利用它我们可以去做分布式服务开发,这篇文章主要介绍了SpringCloud微服务剔除下线功能,需要的朋友可以参考下
    2022-11-11

最新评论