《Spring源碼解析》筆記html
在學習BeanPostProcessor的原理學習完以後,對Spring如何使用充滿好奇,嘗試使用例子進行理解,如下記錄過程:spring
一、使用ApplicationContextAware,能夠指定,在當前函數中獲取到容器上下文,具體使用舉例以下:app
@Component public class Dog implements ApplicationContextAware { //@Autowired private ApplicationContext context; public Dog(){ System.out.println("dog constructor..."); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub this.context = applicationContext; } }
二、在Dog類中經過使用變量context便可獲取Spring的容器上下文,可是具體如何實現?ide
ApplicationContextAware自己並無繼承BeanPostProcess,只繼承Aware接口 函數
public interface ApplicationContextAware extends Aware { /** * Set the ApplicationContext that this object runs in. * Normally this call will be used to initialize the object. * <p>Invoked after population of normal bean properties but before an init callback such * as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()} * or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader}, * {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and * {@link MessageSourceAware}, if applicable. * @param applicationContext the ApplicationContext object to be used by this object * @throws ApplicationContextException in case of context initialization errors * @throws BeansException if thrown by application context methods * @see org.springframework.beans.factory.BeanInitializationException */ void setApplicationContext(ApplicationContext applicationContext) throws BeansException; }
經過代碼運行,能夠看到調用,該setApplicationContext是經過類ApplicationContextAwareProcessor實現,post
查看ApplicationContextAwareProcessor:學習
class ApplicationContextAwareProcessor implements BeanPostProcessor {}
當容器中的Bean賦值後,會遍歷容器中的BeanPostProcessor ,挨個執行,天然會執行到ApplicationContextAwareProcessor 的postProcessBeforeInitialization()方法。this
在其中執行的是this.invokeAwareInterfaces(bean)函數,查看invokeAwareInterfaces()函數代碼:spa
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); } } }
三、從代碼中能夠看出code
該函數只會執行實現Aware接口的Bean,咱們的實現類Dog實現的是ApplicationContextAware
即會執行其相關的代碼,自動爲Dog中變量進行賦值。
四、引伸學習Aware
自定義組件實現xxxAware;在建立對象的時候,會調用接口規定的方法注入相關組件;Aware;
把Spring底層一些組件注入到自定義的Bean中;
xxxAware:部分Aware接口的功能使用xxxProcessor;
ApplicationContextAware==》ApplicationContextAwareProcessor;
例如BeanNameAware接口的實現見4.3;
4.1 Aware的子接口如圖所示:
4.2 舉例Aware的使用方式
@Component public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // TODO Auto-generated method stub System.out.println("傳入的ioc:"+applicationContext); this.applicationContext = applicationContext; } @Override public void setBeanName(String name) { // TODO Auto-generated method stub System.out.println("當前bean的名字:"+name); } //StringValueResolver:Resolve the given String value, for example parsing placeholders. @Override public void setEmbeddedValueResolver(StringValueResolver resolver) { // TODO Auto-generated method stub String resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}"); System.out.println("解析的字符串:"+resolveStringValue); } }
4.2 BeanNameAware接口的實現
首先在函數initializeBean中,會調用invokeAwareMethods函數,其中Beanpostprocess的兩個方法及初始化方法都是在該函數中進行執行。
進入invokeAwareMethods函數
在函數中能夠觀察到部分Aware的子接口均是在此實現。