• Spring的感知能力 Aware


      在 Spring 框架中有一个 org.springframework.beans.factory.Aware 接口,

    Aware 是感知感应的意思,那么此接口的作用就是为 Spring 中的 bean 提供了感知外界的能力。

    Aware接口本身只是一个标记接口,Spring 中提供了一系列具有具体感知能力的接口,它们都继承自 Aware 接口,

      部分如下:

      LoadTimeWeaverAware:加载 Spring Bean 时织入第三方模块,如AspectJ

      BeanClassLoaderAware:加载 Spring Bean 的类加载器

      BootstrapContextAware:资源适配器 BootstrapContext,如JCA,CCI

      ResourceLoaderAware:底层访问资源的加载器

      BeanFactoryAware:声明 BeanFactory

      PortletConfigAware:PortletConfig

      PortletContextAware:PortletContext

      ServletConfigAware:ServletConfig

      ServletContextAware:ServletContext

      MessageSourceAware:国际化

      ApplicationEventPublisherAware:应用事件

      NotificationPublisherAware:JMX通知

      BeanNameAware:声明 Spring Bean 的名字

      此处以 BeanNameAware 举例,其内部包含了一个 setBeanName 方法,所以当一个 bean 继承了此接口,并定义一个 beanName 的属性,

    则在 Spring 容器初始化这个 bean 的时候,会调用这个 setBeanName 方法,注入这个 beanName。

      不同的 Aware 注入对应的外界信息的时机是不一样的,具体也分为两类:

      1. BeanNameAware/BeanClassLoaderAware/BeanFactoryAware

      这三类 Aware 生效的时机是在容器创建 bean 的最后一步完成,具体的调用顺序如下:

      getBean(String beanName)

        doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)

          getSingleton(String beanName, ObjectFactory<?> singletonFactory)

      在 getSingleton 会回调

      createBean(String beanName, RootBeanDefinition mbd, Object[] args)

        doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

          initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)

      最终在 initializeBean 内会调用如下方法,此处分别调用了对应的 setXXX 方法,外部信息得以注入

    private void invokeAwareMethods(final String beanName, final Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware) bean).setBeanName(beanName);
                }
                if (bean instanceof BeanClassLoaderAware) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
                }
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                }
            }
        }

      2. LoadTimeWeaverAware/ApplicationContextAware/ServletContextAware/MessageSourceAware 等

      这一类 Aware 是通过 BeanPostProcessor bean后置处理器实现外部信息注入的。

      同样在上述的 initializeBean 方法内会调用如下方法

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
                result = beanProcessor.postProcessBeforeInitialization(result, beanName);
                if (result == null) {
                    return result;
                }
            }
            return result;
        }

    此处会调用容器中注册的所有的 BeanPostProcessor 的 postProcessBeforeInitialization 方法,而 ApplicationContextAwareProcessor 是默认注册到容器内的,其 postProcessBeforeInitialization 方法内会调用如下方法:

    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(this.embeddedValueResolver);
                }
                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);
                }
            }
        }

    所以 bean 只要继承了 EnvironmentAware,ResourceLoaderAware 就具备相应的感知能力。

  • 相关阅读:
    jQuery 自执行函数
    IRelationalOperator空间关系接口简介
    9.2 空间拓扑运算[转]
    解决关于ArcGIS10.2服务手动启动的问题
    Multipart to single part feature
    Multipart polyline to single part lines
    VS2015 C#6.0 中的没有实现/支持的特性
    VS2015 C#6.0 中的那些新特性
    ArcGIS中各种合并要素(Union、Merge、Append、Dissolve)的异同点分析 转载
    FME2010 案例分析: 动态批量转换
  • 原文地址:https://www.cnblogs.com/techroad4ca/p/11651310.html
Copyright © 2020-2023  润新知