前言:在【spring源碼分析】IOC容器初始化(十一)中提到了初始化bean的三個步驟:html
這裏咱們就來看下Spring是如何激活Aware方法的。spring
Aware是一個空接口,包路徑爲:org.springframework.beans.factory.Aware,它具備標識做用,實現了該接口的bean具備被Spring容器通知的能力,通知的方式採用回調的方式。ide
因爲Aware是一個空接口,實際的方法簽名由各個子類來肯定,其該接口一般只會有一個接收單參數的set方法,該set方法的命名方式爲set+去掉接口中的Aware後綴,即:setxxx(),那Spring中是如何處理實現Aware接口的bean的呢。在invokeAwareMethods方法中能夠看到以下代碼:源碼分析
1 // AbstractAutowireCapableBeanFactory 2 private void invokeAwareMethods(final String beanName, final Object bean) { 3 if (bean instanceof Aware) { 4 // BeanNameAware 5 if (bean instanceof BeanNameAware) { 6 ((BeanNameAware) bean).setBeanName(beanName); 7 } 8 // BeanClassLoaderAware 9 if (bean instanceof BeanClassLoaderAware) { 10 ClassLoader bcl = getBeanClassLoader(); 11 if (bcl != null) { 12 ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); 13 } 14 } 15 // BeanFactoryAware 16 if (bean instanceof BeanFactoryAware) { 17 ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); 18 } 19 } 20 }
分析:測試
首先判斷bean是否實現了Aware接口,若是是則調用實例的setXXX()方法給實例設置xxx屬性,在invokeAwareMethods方法中,主要處理BeanNameAware、BeanClassLoaderAware、BeanFactoryAware三種接口,也從側面證明了Spring只會處理實現了這三種接口中任意一個的bean實例。this
下面就演示Spring是如何處理實現這三個接口的bean的:spa
1 public class UserDefinedAware implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware { 2 3 private String name; 4 private ClassLoader classLoader; 5 private BeanFactory beanFactory; 6 7 @Override 8 public void setBeanName(String name) { 9 System.out.println("調用了 BeanNameAware 的 setBeanName方法"); 10 this.name = name; 11 } 12 13 @Override 14 public void setBeanClassLoader(ClassLoader classLoader) { 15 System.out.println("調用了 BeanClassLoader 的 setBeanClassLoader 方法"); 16 this.classLoader = classLoader; 17 } 18 19 @Override 20 public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 21 System.out.println("調用了 BeanFactoryAware 的 setBeanFactory 方法"); 22 this.beanFactory = beanFactory; 23 } 24 25 public void showMsg() { 26 System.out.println("beanName=" + this.name); 27 System.out.println("classLoader=" + this.classLoader.getClass()); 28 System.out.println("是否爲單例=" + beanFactory.isSingleton(this.name)); 29 } 30 }
測試方法以下:code
1 /** 2 * Aware接口演示 3 */ 4 @Test 5 public void awareTest() { 6 ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:com/dev/config/aware/aware.xml"); 7 UserDefinedAware userDefinedAware = context.getBean(UserDefinedAware.class); 8 userDefinedAware.showMsg(); 9 }
輸出結果以下:xml
從以上示例基本上能夠了解 Aware接口 真正的含義:感知,實際上是Spring容器在初始化主動檢測當前bean是否實現了Aware接口,若是實現了則回調其set方法將相應的參數設置給該bean,這個時候該bean就從Spring容器中取得了相應的資源。因此Aware接口的做用就是讓實現該接口的bean能從Spring容器中取得相應的資源。這裏如name、ClassLoader、beanFactory。htm
下面列出一些經常使用的Aware接口,便於往後查詢:
by Shawn Chen,2019.04.29,晚上。