1、Aware接口,這個也是spring的拓展之一,爲啥要單獨拿出來說呢,由於他相比於BeanFactoryPostProcessor,BeanPostProcessor的實用性更加高,而且在具體的業務中也能夠靈活使用,主要是可以達到解耦的目的。html
2、經常使用的Aware接口有:第一類:BeanNameAware/BeanClassLoaderAware/BeanFactoryAware。 第二類:EmbeddedValueResolverAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware。這兩類到底有啥區別類,其實沒有太大的區別。可是在源碼實現中仍是存在很大的差異的(後面統一說道)。java
3、源碼實現:spring
一、第一類:BeanNameAware/BeanClassLoaderAware/BeanFactoryAwareapp
1)實現方式:ide
import org.springframework.beans.factory.BeanNameAware; /** * BeanNameAware/BeanClassLoaderAware/BeanFactoryAware相似 */ public class TestBeanAware implements BeanNameAware{ private String beanName; @Override public void setBeanName(String beanName) { System.out.println(beanName); this.beanName = beanName; } public String getBeanName() { return beanName; } }
2)有啥區別post
這裏簡單說明一下:相對於普通的bean,這裏能夠獲取到beanName/classLoader/beanFactory。是對普通bean的一種加強,而後合理的應用纔是關鍵測試
3)源碼實現部分:this
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean); return null; } }, this.getAccessControlContext()); } else { this.invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); } try { this.invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable var6) { throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; } private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof BeanNameAware) { ((BeanNameAware)bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader()); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware)bean).setBeanFactory(this); } }
4)什麼時候調用:spring源碼-bean之加載-2 的3)點d.3 doCreateBean中的initializeBean()部分開始,因此這個實際上是在getBean的時候纔會調用。url
5)測試的時候發現:在加強容器中refresh方法中finishBeanFactoryInitializationh會完成這部分的調用spa
二、第二類:EmbeddedValueResolverAware/ResourceLoaderAware/ApplicationEventPublisherAware/MessageSourceAware/ApplicationContextAware
1)實現方式:這裏舉兩個例子EmbeddedValueResolverAware,ApplicationEventPublisherAware
a.EmbeddedValueResolverAware
import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.util.StringValueResolver; import javax.annotation.PostConstruct; public class TestEmbeddedValueResolverAware implements EmbeddedValueResolverAware { private StringValueResolver stringValueResolver; @Override public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) { this.stringValueResolver = stringValueResolver; } public String getProperties (String name) { String elName = "${"+ name +"}"; return stringValueResolver.resolveStringValue(elName); } @PostConstruct public void test() { System.out.println(getProperties("name")); } }
注意:這裏是讀取方式配置
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>aware.properties</value> </list> </property> </bean>
aware.properties
name=test
age=25
sex=boy
疑問:和這個有啥關係,看在StringValueResolver能夠知道,這裏的StringValueResolver指向的是PropertyPlaceholderConfigurer的內部類PlaceholderResolvingStringValueResolver,固然具體的實現有不一樣的方式
private class PlaceholderResolvingStringValueResolver implements StringValueResolver { private final PropertyPlaceholderHelper helper; private final PlaceholderResolver resolver; public PlaceholderResolvingStringValueResolver(Properties props) { this.helper = new PropertyPlaceholderHelper(PropertyPlaceholderConfigurer.this.placeholderPrefix, PropertyPlaceholderConfigurer.this.placeholderSuffix, PropertyPlaceholderConfigurer.this.valueSeparator, PropertyPlaceholderConfigurer.this.ignoreUnresolvablePlaceholders); this.resolver = PropertyPlaceholderConfigurer.this.new PropertyPlaceholderConfigurerResolver(props, (PropertyPlaceholderConfigurer.PropertyPlaceholderConfigurerResolver)null); } public String resolveStringValue(String strVal) throws BeansException { String value = this.helper.replacePlaceholders(strVal, this.resolver); return value.equals(PropertyPlaceholderConfigurer.this.nullValue) ? null : value; } }
b.ApplicationEventPublisherAware
import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import javax.annotation.PostConstruct; public class TestApplicationEventPublisherAware implements ApplicationEventPublisherAware { private ApplicationEventPublisher publisher; @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } public ApplicationEventPublisher getPublisher() { return publisher; } public class TestEvent extends ApplicationEvent { private Object object; public TestEvent(Object source, Object object) { super(source); this.object = object; } public Object getObject() { return object; } } @PostConstruct public void test() { publisher.publishEvent(new TestEvent(this, "test")); }
import org.springframework.context.ApplicationListener; public class TestListener implements ApplicationListener<TestApplicationEventPublisherAware.TestEvent>{ @Override public void onApplicationEvent(TestApplicationEventPublisherAware.TestEvent testEvent) { System.out.println("TestEvent is Happen" + testEvent.getObject()); } }
發佈,監聽的過程相信。在實際業務中很經常使用吧。這裏監聽過程後面會講,這裏不細說。
注意:這裏用aware的接口方式實現發佈,監聽過程,會比直接調用的方式更加解耦。
2)重點來了,這玩意在哪裏調用的呢。其實咱們以前咱們忽略了一個重點。
a.先看調用方式
看到postProcessBeforeInitialization應該感到高興了,由於這不就是實現了BeanPostProcessor接口的前置調用過程嗎。
有問題能夠參考:spring源碼-BeanPostProcessor-3.3
b.疑問:咱們並無手動去實現BeanPostProcessor的接口而且對aware接口作處理啊。
經過debug和查看堆棧信息能夠知道方法調用在ApplicationContextAwareProcessor類裏面
package org.springframework.context.support; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.MessageSourceAware; import org.springframework.context.ResourceLoaderAware; import org.springframework.util.StringValueResolver; class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; } public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException { AccessControlContext acc = null; if (System.getSecurityManager() != null && (bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } if (acc != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean); return null; } }, acc); } else { this.invokeAwareInterfaces(bean); } return bean; } private void invokeAwareInterfaces(Object bean) { if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(new ApplicationContextAwareProcessor.EmbeddedValueResolver(this.applicationContext.getBeanFactory())); } 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); } } public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; } private static class EmbeddedValueResolver implements StringValueResolver { private final ConfigurableBeanFactory beanFactory; public EmbeddedValueResolver(ConfigurableBeanFactory beanFactory) { this.beanFactory = beanFactory; } public String resolveStringValue(String strVal) { return this.beanFactory.resolveEmbeddedValue(strVal); } } }
c、還有一個問題ApplicationContextAwareProcessor在哪裏註冊的呢?
經過源碼方式查看到在refresh()的this.prepareBeanFactory(beanFactory);中提早準備了ApplicationContextAwareProcessor
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(this.getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this)); beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); if (beanFactory.containsBean("loadTimeWeaver")) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } Object systemEnvironment; if (!beanFactory.containsBean("systemProperties")) { try { systemEnvironment = System.getProperties(); } catch (AccessControlException var4) { systemEnvironment = new ReadOnlySystemAttributesMap() { protected String getSystemAttribute(String propertyName) { try { return System.getProperty(propertyName); } catch (AccessControlException var3) { if (AbstractApplicationContext.this.logger.isInfoEnabled()) { AbstractApplicationContext.this.logger.info("Not allowed to obtain system property [" + propertyName + "]: " + var3.getMessage()); } return null; } } }; } beanFactory.registerSingleton("systemProperties", systemEnvironment); }
四:Aware接口部分就這麼多吧,這裏沒有具體些實現和用法,可是相對於BeanFactoryPostProcessor,BeanPostProcessor。Aware在實際應用中會更加經常使用,這一部分是spring提供出來的拓展,也是必要重要的一個部分。
固然,我這裏可能還存在一些紕漏,還請大佬指出來!