深入理解Spring IOC之扩展篇(四)、Aware接口

简介: 深入理解Spring IOC之扩展篇(四)、Aware接口

本篇讲的是Spring中的Aware接口,也应该是整个系列中最简单的一篇了,但是简单并不代表这玩意不重要,我们很多时候还是会用Aware接口去为我们做事情的。

我们知道,使用了Spring容器之后,我们创建对象这件事情完完全全的交给了Spring,在创建好了之后我们直接拿来用就可以了,容器内的东西对于我们的bean来说完全是透明的。为了让我们的bean可以感知到容器内的一些东西,所以Spring为我们提供了Aware接口,看过我之前文章的小伙伴肯定都知道,在初始化bean的时候有这么一段代码:


private void invokeAwareMethods(final String beanName, final Object bean) {
    // 所谓的xxxAware,就是让这个bean和xxx产生关联
    if (bean instanceof Aware) {
      // 设置名称
      if (bean instanceof BeanNameAware) {
        ((BeanNameAware) bean).setBeanName(beanName);
      }
      // 类加载器
      if (bean instanceof BeanClassLoaderAware) {
        ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
      }
      // 我们有时候使用BeanFactoryAware去拿BeanFactory,就是在这步设置的
      if (bean instanceof BeanFactoryAware) {
        ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
    }
  }


上面这段代码便是处理其中三种Aware的逻辑,我们分别看看这三种Aware的代码:

BeanNameAware:


public interface BeanNameAware extends Aware {
  void setBeanName(String name);
}


BeanClassLoaderAware:


public interface BeanClassLoaderAware extends Aware {
  void setBeanClassLoader(ClassLoader classLoader);
}


BeanFactoryAware:


public interface BeanFactoryAware extends Aware {
  void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}


这三个Aware其实也就是让我们的bean可以知道自己名字,自己的ClassLoader是哪个,加载自己的BeanFactory是哪个,结合我们上面的代码我们知道其实设置这三个Aware是在bean的生命周期内设置的。

那么还有哪些常见的Aware呢?我自己最常用的一个就是ApplicationContextAware,这个接口的代码我就不贴出来了,因为和上面是一样的,就一个set方法而已,那么又是在哪个地方给我们的bean执行了setApplicationContext的方法呢?我们之前文章中介绍AbstractApplicationContext的refresh方法的时候,其中有个prepareBeanFactory方法,这个方法中有这么一句代码:


1686812318527.png


只看画红框的地方就行了,我们可以看到,spring在这里增加了一个ApplicationContextAwareProcessor,这个玩意的本质上是个BeanPostProcessor,那么这玩意干了什么事情呢?我们一起来看下它的代码:


@Override
  public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
    AccessControlContext acc = null;
    if (System.getSecurityManager() != null &&
        (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    }
    //特权执行和普通执行下面的方法
    if (acc != null) {
      AccessController.doPrivileged(new PrivilegedAction<Object>() {
        @Override
        public Object run() {
          invokeAwareInterfaces(bean);
          return null;
        }
      }, acc);
    }
    else {
      invokeAwareInterfaces(bean);
    }
    return bean;
  }
  // 上面调用了这个
  private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
      if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      }
      if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
            new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
      }
      if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      }
      if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      }
      if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      }
      if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      }
    }
  }


这个类只是实现了前置处理这个方法,前置处理什么时候执行的我就不说了,看到这里的人应该是清楚的。这段代码你看我连注释都很少,因为真的很简单,就是检测你是不是实现了这个Aware接口,如果实现了,就给你set上相应的对象而已。其中invokeAwareInterfaces中还有几个其他的Aware,但是说真的,这几个用的都不多,我自己都很少见过业务中使用这几个的,如果读者有兴趣可以自己研究下这几个。

目录
相关文章
|
27天前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
27天前
|
XML Java 数据格式
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
这篇文章是Spring5框架的入门教程,详细讲解了IOC容器中Bean的自动装配机制,包括手动装配、`byName`和`byType`两种自动装配方式,并通过XML配置文件和Java代码示例展示了如何在Spring中实现自动装配。
Spring5入门到实战------6、IOC容器-Bean管理XML方式(自动装配)
|
27天前
|
XML Java 数据格式
Spring5入门到实战------2、IOC容器底层原理
这篇文章深入探讨了Spring5框架中的IOC容器,包括IOC的概念、底层原理、以及BeanFactory接口和ApplicationContext接口的介绍。文章通过图解和实例代码,解释了IOC如何通过工厂模式和反射机制实现对象的创建和管理,以及如何降低代码耦合度,提高开发效率。
Spring5入门到实战------2、IOC容器底层原理
|
27天前
|
XML Java 数据格式
Spring5入门到实战------8、IOC容器-Bean管理注解方式
这篇文章详细介绍了Spring5框架中使用注解进行Bean管理的方法,包括创建Bean的注解、自动装配和属性注入的注解,以及如何用配置类替代XML配置文件实现完全注解开发。
Spring5入门到实战------8、IOC容器-Bean管理注解方式
|
21天前
|
存储 SQL Java
|
22天前
|
自然语言处理 Java 开发者
简单了解下Spring中的各种Aware接口实现依赖注入
【8月更文挑战第21天】在Spring框架中,Aware接口系列是一种特殊的机制,它允许Bean在初始化过程中获取到Spring容器或容器中的特定资源,从而实现了更加灵活和强大的依赖注入方式。本文将围绕Spring中的各种Aware接口,详细探讨它们如何帮助开发者在工作和学习中更好地实现依赖注入。
35 0
|
4月前
|
XML Java 数据格式
④【Spring】IOC - 基于注解方式 管理bean
④【Spring】IOC - 基于注解方式 管理bean
64 0
|
4月前
|
XML Java 数据格式
②【Spring】一文精通:IOC - 基于XML方式管理Bean
②【Spring】一文精通:IOC - 基于XML方式管理Bean
160 0
|
3月前
|
XML Java 数据格式
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
Spring5系列学习文章分享---第一篇(概述+特点+IOC原理+IOC并操作之bean的XML管理操作)
36 1
|
3月前
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
41 0