Spring中Aware的原理

之前一直不太知道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能夠調用到方法從而實現我們所謂的感知

發佈了113 篇原創文章 · 獲贊 62 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章