4....
ApplicationContextAware:实现该接口的对象可以获取到一个 ApplicationContext 对象,通过 ApplicationContext 可以获取容器中的 Bean、环境等信息。
@Service public class UserService implements BeanNameAware { private String beanName; @Override public void setBeanName(String name) { this.beanName = name; } // 堆代码 duidaima.com @Override public String toString() { return "UserService{" + "beanName='" + beanName + '\'' + '}'; } }让当前 bean 实现 BeanNameAware 接口,并重写 setBeanName 方法,这个方法会在 Spring 容器初始化 Bean 的时候自动被调用,我们就可以据此获取到 bean 的名称了。再比如我想做一个工具 Bean,用来查找其他 Bean,那么我可以使用如下方式:
@Component public class BeanUtils implements BeanFactoryAware { private static BeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } public static <T> T getBean(Class<T> clazz) { return (T) beanFactory.getBean(clazz); } }让当前 Bean 实现 BeanFactoryAware 接口并重写 setBeanFactory 方法,在系统初始化当前 Bean 的时候,会自动调用 setBeanFactory 方法,进而将 beanFactory 变量传进来。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { invokeAwareMethods(beanName, 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, ex.getMessage(), ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }在这个方法一进来,首先有一个 invokeAwareMethods,这个就是用来触发 Aware 的,来看下:
private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware beanNameAware) { beanNameAware.setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware beanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { beanClassLoaderAware.setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware beanFactoryAware) { beanFactoryAware.setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }小伙伴们可以看到,BeanNameAware、BeanClassLoaderAware 以及 BeanFactoryAware 这三种类型的 Aware 是在这里触发的。每种 Aware 因为功能不同,因此作用的时机也不同。
@Override @Nullable public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware || bean instanceof ApplicationStartupAware)) { return bean; } invokeAwareInterfaces(bean); return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof Aware) { if (bean instanceof EnvironmentAware environmentAware) { environmentAware.setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware embeddedValueResolverAware) { embeddedValueResolverAware.setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware resourceLoaderAware) { resourceLoaderAware.setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware applicationEventPublisherAware) { applicationEventPublisherAware.setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware messageSourceAware) { messageSourceAware.setMessageSource(this.applicationContext); } if (bean instanceof ApplicationStartupAware applicationStartupAware) { applicationStartupAware.setApplicationStartup(this.applicationContext.getApplicationStartup()); } if (bean instanceof ApplicationContextAware applicationContextAware) { applicationContextAware.setApplicationContext(this.applicationContext); } } }大家看下,这七种类型的 Aware 是在这里被触发的。另外像 ImportAware 是在 ImportAwareBeanPostProcessor#postProcessBeforeInitialization 方法中处理的;LoadTimeWeaverAware 是在 、LoadTimeWeaverAwareProcessor#postProcessBeforeInitialization 方法中处理的。