Spring扩展点之Aware接口族

  • 2019 年 10 月 4 日
  • 笔记

Spring中提供了各种Aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:BeanFactoryAware,BeanNameAware,ApplicationContextAware,EnvironmentAware,BeanClassLoaderAware等

这些Aware的作用都可以从命名得知

Aware的处理

其中BeanNameAwareBeanClassLoaderAwareBeanFactoryAware这三个是直接在bean的初始化之前就处理了的,具体代码在AbstractAutowireCapableBeanFactory.initializeBean方法中:

protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {      // 判断对象实现的接口类型,处理特定的三种接口类型:BeanNameAware、BeanClassLoaderAware和BeanFactoryAware。      if (bean instanceof BeanNameAware) {          ((BeanNameAware) bean).setBeanName(beanName);      }        if (bean instanceof BeanClassLoaderAware) {          ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());      }        if (bean instanceof BeanFactoryAware) {          ((BeanFactoryAware) bean).setBeanFactory(this);      }      // 开始Bean初始化前处理、初始化、初始化后处理      Object wrappedBean = bean;      if (mbd == null || !mbd.isSynthetic()) {          wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);      }        try {          invokeInitMethods(beanName, wrappedBean, mbd);      }      catch (Throwable ex) {          throw new BeanCreationException(                  (mbd != null ? mbd.getResourceDescription() : null),                  beanName, "Invocation of init method failed", ex);      }        if (mbd == null || !mbd.isSynthetic()) {          wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);      }      return wrappedBean;  }

除了这三种之外的那些Aware接口的实现就不太一样了,它们都是利用BeanPostProcessor接口完成的,关于BeanPostProcessor接口的原理可以这篇文章:Spring扩展点之BeanPostProcessor

ApplicationContextAware就是利用ApplicationContextAwareProcessor实现的:

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((PrivilegedAction<Object>) () -> {          //具体实现          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(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);        }      }    }

ApplicationContextAwareProcessor的注册奥秘在AbstractApplicationContext.prepareBeanFactory方法中:

beanFactory.setBeanClassLoader(getClassLoader());  beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this));  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));  beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);  beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);  beanFactory.ignoreDependencyInterface(MessageSourceAware.class);  beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);