一个好的框架必备的特性至少得有开闭原则,可扩展性BeanFactoryPostProcessor
也是Spring可扩展性的一个体现,我们读一下这个接口的源码
public interface BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改也可以add属性值。
bean工厂后置处理器—>构造方法—>init-method。
3.1、测试代码:
package com.atguigu.ext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.atguigu.bean.Blue;
@ComponentScan("com.atguigu.ext")
@Configuration
public class ExtConfig {
@Bean
public Blue blue(){
return new Blue();
}
}
import org.junit.Test;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.atguigu.ext.ExtConfig;
public class IOCTest_Ext {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
//发布事件;
applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {
});
applicationContext.close();
}
}
3.2、ApplicationListener的应用
ApplicationListener:监听容器中发布的事件。事件驱动模型开发;
public interface ApplicationListener
监听 ApplicationEvent 及其下面的子事件;
步骤:
1)、写一个监听器(ApplicationListener实现类)来监听某个事件(ApplicationEvent及其子类)
@EventListener;
原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
2)、把监听器加入到容器;
3)、只要容器中有相关事件的发布,我们就能监听到这个事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
ContextClosedEvent:关闭容器会发布这个事件;
4)、发布一个事件:
applicationContext.publishEvent();
3.3、ApplicationListener的原理
【事件发布流程】:
publishEvent(new ContextRefreshedEvent(this));
1)、获取事件的多播器(派发器):getApplicationEventMulticaster()
2)、multicastEvent派发事件:
3)、获取到所有的ApplicationListener;
for (final ApplicationListener> listener : getApplicationListeners(event, type)) {
1)、如果有Executor,可以支持使用Executor进行异步派发;
Executor executor = getTaskExecutor();
2)、否则,同步的方式直接执行listener方法;invokeListener(listener, event);
拿到listener回调onApplicationEvent方法;
注解:为了便于理解下面只保留了最核心的源码,只在关键的调用地方打中文注释
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
@Override
public void publishEvent(ApplicationEvent event) {
publishEvent(event, null);
}
protected void publishEvent(Object event, ResolvableType eventType) {
ApplicationEvent applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent) event;
}
else {
applicationEvent = new PayloadApplicationEvent
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
private Executor taskExecutor;
private ErrorHandler errorHandler;
@Override
public void multicastEvent(ApplicationEvent event) {
multicastEvent(event, resolveDefaultEventType(event));
}
@Override
public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
for (final ApplicationListener> listener : getApplicationListeners(event, type)) {
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(new Runnable() {
@Override
public void run() {
invokeListener(listener, event);
}
});
}
else {
invokeListener(listener, event);
}
}
}
}
3.4、 @EventListener
3.4.1、基于注解的方式创建监听器:
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
@Service
public class UserInfoService {
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
System.out.println("UserService。。监听到的事件:"+event);
}
}
3.4.2 @EventListener注解原理
原理:使用EventListenerMethodProcessor处理器来解析方法上的@EventListener;
再看SmartInitializingSingleton 这个类的原理即可
public class EventListenerMethodProcessor implements SmartInitializingSingleton, ApplicationContextAware
SmartInitializingSingleton 原理:->执行这个方法afterSingletonsInstantiated();
afterSingletonsInstantiated();是在所有bean初始化完成之后调用的,
断点在EventListenerMethodProcessor.afterSingletonsInstantiated()方法上查看执行流程
1)、ioc容器创建对象并refresh();
2)、finishBeanFactoryInitialization(beanFactory);初始化剩下的单实例bean;
1)、DefaultListableBeanFactory.preInstantiateSingletons()->先创建所有的单实例bean;getBean();
2)、获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;如果是就调用afterSingletonsInstantiated();
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
//ioc容器创建对象并refresh();
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
// 初始化剩下的单实例bean
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
return getEnvironment().resolvePlaceholders(strVal);
}
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
//先创建所有的单实例bean
beanFactory.preInstantiateSingletons();
}
}
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List beanNames = new ArrayList(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
//获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
待续。。。