之前一直不太知道Aware這個東西有什麼用,看了看官網,別人的博客,今天算是有點眉目了,在此做一個筆記
在Spring中有一個接口,但是這個接口中沒有一個方法,那麼它有什麼用呢,通過註釋知道,這個接口起到的是一個標記作用,或者說的高大一些,做到面向接口編程,具體需要實現的工作還是需要子類來實現
/**
* A marker superinterface indicating that a bean is eligible to be notified by the
* Spring container of a particular framework object through a callback-style method.
* The actual method signature is determined by individual subinterfaces but should
* typically consist of just one void-returning method that accepts a single argument.
*
* <p>Note that merely implementing {@link Aware} provides no default functionality.
* Rather, processing must be done explicitly, for example in a
* {@link org.springframework.beans.factory.config.BeanPostProcessor}.
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
* for an example of processing specific {@code *Aware} interface callbacks.
*
* @author Chris Beams
* @author Juergen Hoeller
* @since 3.1
*/
public interface Aware {
}
子類繼承這個接口能做什麼,我們先看看它有哪些子接口
如上圖,我們看到了Aware有這麼多子接口,而aware單詞本身有知道、感知的作用,結合官網,別人的博客知道,在spring實例化bean的過程中,如果我們定義的bean實現了這些Aware,那麼spring就會感知到這些Bean需要的東西
舉例:BeanNameAware
如果我們定義的類實現了這個接口,那麼在實例化這個bean的時候,通過後置處理器執行到BeanNameAware的setBeanName方法(),其他的Aware也是同樣的原理,只是針對不同的Aware,具體調用的時機可能有所不同,具體的我們後續分析
需要注意的是,我們自己定義一個Aware在Spring中是沒有辦法識別的,原因我們看看源碼就知道了
舉例說明,自定義一個Bean,實現ApplicationContextAware
/**
* @ClassName ApplicationContextAwareBeanTest
* @Author mjlft
* @Date 2020/2/9 14:00
* @Version 1.0
* @Description 測試ApplicationContextAware的調用時機
*/
@Component
public class ApplicationContextAwareBeanTest implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("在這裏執行ApplicationContextAware");
}
}
根據方法調用棧可以知道, 在applicationrefresh過程中創建bean時,會執行如下方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
//這個地方調用接口Aware的方法,
//例如當前bean實現了ApplicationContextAware接口,那麼這個地方會調用這個接口的
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//執行bean後置處理,包括自定義的還有系統定義的0,
// @PostCounstruct由系統提供的CommonAnnotationBeanPostProcessor進行處理
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//這裏執行實現InitializingBean接口的方法
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()) {
//執行beanPostProcessor的applyBeanPostProcessorsAfterInitialization方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
這個方法最開始就調用了invokeAwareMethods(beanName, bean);而這裏的這個方法只處理了幾個Aware,我們測試樣例中的ApplicationContextAware也不是在這裏執行的,所以還得跟蹤方法棧
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) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
最後在ApplicationContextAwareProcessor的一個方法中知道了invokeAwareInterfaces()方法的調用
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);
}
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
當然我們這裏只是一個例子,可能對於別的Aware,在其他的後置處理中進行了處理,總之原理我們是知道,爲什麼實現了Aware接口後,spring能夠調用到方法從而實現我們所謂的感知