《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的子接口均是在此实现。