zoukankan      html  css  js  c++  java
  • 【Spring】Aware 接口原理(九)

    一、Aware 接口介绍

      Aware接口从字面上翻译过来是感知捕获的含义。单纯的bean(未实现Aware系列接口)是没有知觉的;实现了Aware系列接口的bean可以访问Spring容器。这些Aware系列接口增强了Spring bean的功能,但是也会造成对Spring框架的绑定,增大了与Spring框架的耦合度。(Aware是“意识到的,察觉到的”的意思,实现了Aware系列接口表明:可以意识到、可以察觉到)

      代码:

    1 public interface Aware {
    2 
    3 }

    二、Aware 接口扩展点图

      

    三、Aware 接口实现原理

    1、在Spring中,获取bean时,初始化bean

      context.getBean()->doGetBean()->createBeat()->doCreateBeat()->initializeBean()

      initializeBean() 方法如下:

     1 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
     2     if (System.getSecurityManager() != null) {
     3         AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
     4             invokeAwareMethods(beanName, bean);
     5             return null;
     6         }, getAccessControlContext());
     7     } else {
     8         // 若bean实现了XXXAware接口进行方法的回调
     9         invokeAwareMethods(beanName, bean);
    10     }
    11 
    12     Object wrappedBean = bean;
    13     if (mbd == null || !mbd.isSynthetic()) {
    14         // 支持初始化前bean的后置处理器
    15         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    16     }
    17 
    18     try {
    19         // 调用初始化方法
    20         invokeInitMethods(beanName, wrappedBean, mbd);
    21     } catch (Throwable ex) {
    22         throw new BeanCreationException(
    23                 (mbd != null ? mbd.getResourceDescription() : null),
    24                 beanName, "Invocation of init method failed", ex);
    25     }
    26     if (mbd == null || !mbd.isSynthetic()) {
    27         wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    28     }
    29 
    30     return wrappedBean;
    31 }

    2、调用了invokeAwareMethods() 方法
      如果bean实现了Aware接口,就能够执行对应Aware接口的方法

     1 private void invokeAwareMethods(final String beanName, final Object bean) {
     2     if (bean instanceof Aware) {
     3         // bean实现了BeanNameAware
     4         if (bean instanceof BeanNameAware) {
     5             ((BeanNameAware) bean).setBeanName(beanName);
     6         }
     7         // 实现了BeanClassLoaderAware接口
     8         if (bean instanceof BeanClassLoaderAware) {
     9             ClassLoader bcl = getBeanClassLoader();
    10             if (bcl != null) {
    11                 ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
    12             }
    13         }
    14         // 实现了BeanFactoryAware
    15         if (bean instanceof BeanFactoryAware) {
    16             ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
    17         }
    18     }
    19 }

    3、支持初始化前bean的后置处理器

      调用了方法applyBeanPostProcessorsBeforeInitialization(),由于内置在创建了ApplicationContextAwareProcessor后置处理器,那么就会调用此后置处理器的方法

      ApplicationContextAwareProcessor#postProcessBeforeInitialization()如下:

     1 // 初始化前调用 此Bean后置处理器处理
     2 @Override
     3 @Nullable
     4 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     5     if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
     6             bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
     7             bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
     8         return bean;
     9     }
    10 
    11     AccessControlContext acc = null;
    12 
    13     // 获取系统安全管理器,默认获取为空
    14     if (System.getSecurityManager() != null) {
    15         acc = this.applicationContext.getBeanFactory().getAccessControlContext();
    16     }
    17 
    18     if (acc != null) {
    19         AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    20             // 调用Aware接口
    21             invokeAwareInterfaces(bean);
    22             return null;
    23         }, acc);
    24     }
    25     else {
    26         invokeAwareInterfaces(bean);
    27     }
    28 
    29     return bean;
    30 }

    4、后置处理逻辑中调用了invokeAwareInterfaces方法()

     1 // 调用Aware接口
     2 private void invokeAwareInterfaces(Object bean) {
     3     // 判断 bean 属于那种类型,调用对应的方法
     4     if (bean instanceof EnvironmentAware) {
     5         ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
     6     }
     7     if (bean instanceof EmbeddedValueResolverAware) {
     8         ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
     9     }
    10     if (bean instanceof ResourceLoaderAware) {
    11         ((ResourceLoaderAware) bean).    (this.applicationContext);
    12     }
    13     if (bean instanceof ApplicationEventPublisherAware) {
    14         ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    15     }
    16     if (bean instanceof MessageSourceAware) {
    17         ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    18     }
    19     if (bean instanceof ApplicationContextAware) {
    20         ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    21     }
    22 }
  • 相关阅读:
    ZOJ 1002 Fire Net (火力网)
    UVa OJ 117 The Postal Worker Rings Once (让邮差只走一圈)
    UVa OJ 118 Mutant Flatworld Explorers (变体扁平世界探索器)
    UVa OJ 103 Stacking Boxes (嵌套盒子)
    UVa OJ 110 MetaLoopless Sorts (无循环元排序)
    第一次遇到使用NSNull的场景
    NSURL使用浅析
    从CNTV下载《小小智慧树》
    NSDictionary and NSMutableDictionary
    Category in static library
  • 原文地址:https://www.cnblogs.com/h--d/p/14660538.html
Copyright © 2011-2022 走看看