Spring源码阅读目录
第一部分——IOC篇
第一章 Spring之最熟悉的陌生人——IOC
第二章 Spring之假如让你来写IOC容器——加载资源篇
第三章 Spring之假如让你来写IOC容器——解析配置文件篇
第四章 Spring之假如让你来写IOC容器——XML配置文件篇
第五章 Spring之假如让你来写IOC容器——BeanFactory和FactoryBean
第六章 Spring之假如让你来写IOC容器——Scope和属性填充
第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式
第八章 Spring之假如让你来写IOC容器——拓展篇
第九章 Spring之源码阅读——环境搭建篇
第十章 Spring之源码阅读——IOC篇
第二部分——AOP篇
第十一章 Spring之不太熟的熟人——AOP
第十二章 Spring之不得不了解的内容——概念篇
第十三章 Spring之假如让你来写AOP——AOP联盟篇
第十四章 Spring之假如让你来写AOP——雏形篇
第十五章 Spring之假如让你来写AOP——Joinpoint(连接点)篇
第十六章 Spring之假如让你来写AOP——Pointcut(切点)篇
第十七章 Spring之假如让你来写AOP——Advice(通知)上篇
第十八章 Spring之假如让你来写AOP——Advice(通知)下篇
第十九章 Spring之假如让你来写AOP——番外篇:Spring早期设计
第二十章 Spring之假如让你来写AOP——Aspect(切面)篇
第二十一章 Spring之假如让你来写AOP——Weaver(织入器)篇
第二十二章 Spring之假如让你来写AOP——Target Object(目标对象)篇
第二十三章 Spring之假如让你来写AOP——融入IOC容器篇
第二十四章 Spring之源码阅读——AOP篇
第三部分——事务篇
第二十五章 Spring之曾经的老朋友——事务
第二十六章 Spring之假如让你来写事务——初稿篇
第二十七章 Spring之假如让你来写事务——铁三角篇
第二十八章 Spring之假如让你来写事务——属性篇
第二十九章 Spring之假如让你来写事务——状态篇
第三十章 Spring之假如让你来写事务——管理篇
第三十一章 Spring之假如让你来写事务——融入IOC容器篇
第三十二章 Spring之源码阅读——事务篇
第四部分——MVC篇
第三十三章 Spring之梦开始的地方——MVC
第三十四章 Spring之假如让你来写MVC——草图篇
第三十五章 Spring之假如让你来写MVC——映射器篇
第三十六章 Spring之假如让你来写MVC——拦截器篇
第三十七章 Spring之假如让你来写MVC——控制器篇
第三十八章 Spring之假如让你来写MVC——适配器篇
第三十九章 Spring之假如让你来写MVC——番外篇:类型转换
第四十章 Spring之假如让你来写MVC——ModelAndView篇
第四十一章 Spring之假如让你来写MVC——番外篇:数据绑定
第四十二章 Spring之假如让你来写MVC——视图篇
第四十三章 Spring之假如让你来写MVC——上传文件篇
第四十四章 Spring之假如让你来写MVC——异常处理器篇
第四十五章 Spring之假如让你来写MVC——国际化篇
第四十六章 Spring之假如让你来写MVC——主题解析器篇
第四十七章 Spring之假如让你来写MVC——闪存管理器篇
第四十八章 Spring之假如让你来写MVC——请求映射视图篇
第四十九章 Spring之假如让你来写MVC——番外篇:属性操作
第五十章 Spring之假如让你来写MVC——融入IOC容器篇
第五十一章 Spring之源码阅读——MVC篇
第五部分——Boot篇
第五十二章 Spring之再进一步——Boot
第五十三章 Spring之假如让你来写Boot——环境篇
第五十四章 Spring之假如让你来写Boot——注解篇(上)
第五十五章 Spring之假如让你来写Boot——注解篇(下)
第五十六章 Spring之假如让你来写Boot——SPI篇
第五十七章 Spring之假如让你来写Boot——配置文件篇(上)
第五十八章 Spring之假如让你来写Boot——配置文件篇(下)
第五十九章 Spring之假如让你来写Boot——番外篇:再谈Bean定义
第六十章 Spring之假如让你来写Boot——自动装配篇
第六十一章 Spring之假如让你来写Boot——番外篇:杂谈Starter
第六十二章 Spring之假如让你来写Boot——番外篇:重构BeanFactory
第六十三章 Spring之假如让你来写Boot——番外篇:再谈ApplicationContext
第六十四章 Spring之假如让你来写Boot——内嵌Web容器篇
第六十五章 Spring之假如让你来写Boot——Main方法启动篇
第六十六章 Spring之最终章——结语篇
文章目录
前言
对于Spring一直都是既熟悉又陌生,说对它熟悉吧,平时用用没啥问题,但面试的时候被问的一脸懵逼,就很尴尬,都不好意思在简历上写着熟悉Spring了
所以决定花点时间研究研究Spring的源码。主要参考的书籍是:《Spring源码深度解析(第2版)》、《Spring揭秘》、《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》
书接上回,在上篇 第七章 Spring之假如让你来写IOC容器——属性填充特别篇:SpEL表达式 已经实现了属性填充和Spel表达式相关内容。接下来还需要对IOC容器进行一些拓展功能,让我们接着往下看吧
尝试动手写IOC容器
出场人物:A君(苦逼的开发)、老大(项目经理)
背景:老大要求A君在一周内开发个简单的IOC容器
前情提要:A君 做的IOC容器已经可以支持SPel表达式了,现在项目已经进入了收尾阶段,老大要求A君再添加写拓展功能就能结束了。接下来看看A君会如何进行拓展吧。。。
第十二版 内部对象的获取:Aware接口
关于拓展,A君首先想到的是需要暴露一些内部组件出去,在平时工作中,A君就没少去获取spring的内部组件,比如:BeanFactory、ResourceLoader等。当然可以通过get方法进行获取,不过,有更好的方法。没有错,还是他:接口
首先,A君先定义了个标记接口Aware,用来标记这一系列的接口类型。标记接口,顾名思义,只起到标记作用,没有任何方法需要实现。如下:
/**
* 标记接口,标记需要获取容器内部信息
*/
public interface Aware {
}
接着,定义一个获取BeanFactory的接口,只有一个set方法,如下:
import com.hqd.ch03.v12.factory.BeanFactory;
/**
* 获取容器内部BeanFactory组件
*/
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory);
}
再来个获取ResourceLoader的接口,如下:
import com.hqd.ch03.v12.io.ResourceLoader;
/**
* 获取容器内部ResourceLoader组件
*/
public interface ResourceLoaderAware extends Aware {
void setResourceLoader(ResourceLoader resourceLoader);
}
这些接口都是类似的,就不一一赘述了。接着,A君准备为实现了这些接口的bean设值,也简单,只需要在bean初始化之后,调用各自的set方法即可。SpringImitation改造如下:
invokeAwareMethods方法:
完成代码:
import com.hqd.ch03.v12.aware.Aware;
import com.hqd.ch03.v12.aware.BeanFactoryAware;
import com.hqd.ch03.v12.aware.BeanNameAware;
import com.hqd.ch03.v12.aware.ResourceLoaderAware;
import com.hqd.ch03.v12.beans.BeanWrapper;
import com.hqd.ch03.v12.beans.BeanWrapperImpl;
import com.hqd.ch03.v12.config.BeanDefinition;
import com.hqd.ch03.v12.config.MutablePropertyValues;
import com.hqd.ch03.v12.config.Scope;
import com.hqd.ch03.v12.factory.BeanFactory;
import com.hqd.ch03.v12.factory.ConfigurableBeanFactory;
import com.hqd.ch03.v12.factory.FactoryBean;
import com.hqd.ch03.v12.io.ResourceLoader;
import com.hqd.ch03.v12.io.support.DefaultResourceLoader;
import com.hqd.ch03.v12.registry.BeanDefinitionRegistry;
import com.hqd.ch03.v12.registry.support.DefaultSingletonBeanRegistry;
import com.hqd.ch03.v12.registry.support.SimpleBeanDefinitionRegistry;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.beans.PropertyEditor;
import java.util.HashMap;
import java.util.Map;
public abstract class SpringImitationV12 extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>();
protected BeanDefinitionRegistry beanDefinitionRegistry = new SimpleBeanDefinitionRegistry();
/**
* 单例缓存
*/
protected Map<String, Scope> scopeCache = new HashMap<>();
/**
* 资源加载器
*/
protected ResourceLoader resourceLoader = new DefaultResourceLoader();
public static boolean isFactoryDereference(String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
@Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
customEditors.put(requiredType, propertyEditorClass);
}
/**
* 处理传入的name,去除&开头
*
* @param name
* @return
*/
protected String transformedBeanName(String name) {
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
String beanName = name;
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
}
/**
* 区分正常bean还是FactoryBean
*
* @param obj
* @param name
* @param beanName
* @param bd
* @return
*/
protected Object getObjectForBeanInstance(Object obj, String name, String beanName, BeanDefinition bd) {
if (isFactoryDereference(name)) {
if (!(obj instanceof FactoryBean)) {
throw new RuntimeException(String.format("%s 未实现FactoryBean接口", beanName));
}
return obj;
}
if (obj instanceof FactoryBean) {
return ((FactoryBean) obj).getObject();
}
return obj;
}
private void initBean(BeanWrapper beanWrapper, BeanDefinition bd) {
try {
MutablePropertyValues properties = bd.getProperties();
if (properties != null) {
properties.getProperties().forEach(propertyValue -> {
boolean isRef = propertyValue.isRef();
Object value = propertyValue.getValue();
if (isRef) {
value = getBean((String) value);
}
try {
beanWrapper.setPropertyValue(propertyValue.getName(), value, isRef);
//BeanUtils.setProperty(bean, propertyValue.getName(), value);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object createBean(BeanDefinition bd, String beanName) {
try {
Object instance = null;
if (bd.isSingleton()) {//单例
instance = getSingleton(beanName);
if (instance == null) {
instance = doCreate(bd, beanName);
}
addSingleton(beanName, instance);
} else if (bd.isPrototype()) {//多例
instance = doCreate(bd, beanName);
} else {//自定义作用域
String scopeName = bd.getScope();
Scope scope = scopeCache.get(scopeName);
if (scope == null) {
throw new RuntimeException(String.format("[%s]未注册scope", scopeName));
}
instance = scope.get(beanName, () -> doCreate(bd, beanName));
}
if (instance != null) {
invokeAwareMethods(beanName, instance);
}
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 设置Aware接口
*
* @param beanName
* @param bean
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(resourceLoader);
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
}
protected Object doCreate(BeanDefinition bd, String beanName) {
String beanClass = bd.getBeanClass();
try {
Object instance = Class.forName(beanClass).getConstructor().newInstance();
BeanWrapper beanWrapper = new BeanWrapperImpl(instance);
initBeanWrapper(beanWrapper);
addSingletonFactory(beanName, () -> beanWrapper.getWrappedInstance());
//doSomething
initBean(beanWrapper, bd);
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected void initBeanWrapper(BeanWrapper bw) {
/**
* 注册自定义类型转换器
*
*/
registerCustomEditors(bw);
}
/**
* 是否应该区分全局转换器和局部转换器
* 全局为Factory级别,局部为Bean级别
*
* @param bw
*/
protected void registerCustomEditors(BeanWrapper bw) {
if (MapUtils.isNotEmpty(customEditors)) {
customEditors.forEach((key, val) -> {
try {
bw.registerCustomEditor(key, val.getConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@Override
public void registerScope(String scopeName, Scope scope) {
if (StringUtils.isNotBlank(scopeName) && scope != null) {
scopeCache.put(scopeName, scope);
}
}
@Override
public <T> T getBean(String name, Class<T> clazz) {
return (T) doGetBean(name);
}
@Override
public Object getBean(String name) {
return doGetBean(name);
}
protected Object doGetBean(String name) {
String beanName = transformedBeanName(name);
BeanDefinition bd = beanDefinitionRegistry.getBeanDefinition(beanName);
Object bean = createBean(bd, beanName);
bean = getObjectForBeanInstance(bean, name, beanName, bd);
return bean;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
这次的改造相对简单,不过,为了以防万一,A君还是做了个简单的测试,A君定义了个AwareTest,分别实现了各个Aware接口,代码如下:
import com.hqd.ch03.v12.aware.BeanFactoryAware;
import com.hqd.ch03.v12.aware.BeanNameAware;
import com.hqd.ch03.v12.aware.ResourceLoaderAware;
import com.hqd.ch03.v12.factory.BeanFactory;
import com.hqd.ch03.v12.io.ResourceLoader;
import lombok.Data;
@Data
public class AwareTest implements BeanNameAware, BeanFactoryAware, ResourceLoaderAware {
private BeanFactory beanFactory;
private String beanName;
private ResourceLoader resourceLoader;
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
xml做个简单的定义,配置如下:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="awareTest" class="com.hqd.ch03.test.aware.AwareTest"/>
</beans>
测试代码如下:
@Test
public void v12() {
System.out.println("############# 第十二版:Aware接口 #############");
SpringImitationV12 beanFactory = new SpringImitationV12Xml("classpath:v12/bean.xml");
AwareTest awareTest = beanFactory.getBean("awareTest", AwareTest.class);
System.out.println("加载标签对象:" + awareTest);
}
测试结果,如下:
可以看到,几个属性都有值了。A君的第一版拓展改造也就宣告完成了
第十三版 对象初始化的前后置增强:BeanPostProcessor接口
随着第一版改造的完成,A君又琢磨了一下:现在用户不能对bean初始化进行干预,虽然有init方法,但是如果要返回类似于代理的新对象,init方法显然不满足需求
于是乎,A君有定义一个BeanPostProcessor接口,用来对bean初始化时进行前后置增强,代码如下:
/**
* 对bean初始化进行增强
*/
public interface BeanPostProcessor {
/**
* 前置增强
*
* @param bean
* @param beanName
* @return
*/
default Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
/**
* 后置增强
*
* @param bean
* @param beanName
* @return
*/
default Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
SpringImitation主要的修改点在于调用init方法前,先调用BeanPostProcessor 前置方法,调用init方法后,再调用BeanPostProcessor 后置方法,大致修改如下:
initializeBean方法:
applyBeanPostProcessorsBeforeInitialization方法:
applyBeanPostProcessorsAfterInitialization方法:
完整代码:
import com.hqd.ch03.v13.aware.Aware;
import com.hqd.ch03.v13.aware.BeanFactoryAware;
import com.hqd.ch03.v13.aware.BeanNameAware;
import com.hqd.ch03.v13.aware.ResourceLoaderAware;
import com.hqd.ch03.v13.beans.BeanWrapper;
import com.hqd.ch03.v13.beans.BeanWrapperImpl;
import com.hqd.ch03.v13.config.BeanDefinition;
import com.hqd.ch03.v13.config.BeanPostProcessor;
import com.hqd.ch03.v13.config.MutablePropertyValues;
import com.hqd.ch03.v13.config.Scope;
import com.hqd.ch03.v13.factory.BeanFactory;
import com.hqd.ch03.v13.factory.ConfigurableBeanFactory;
import com.hqd.ch03.v13.factory.FactoryBean;
import com.hqd.ch03.v13.io.ResourceLoader;
import com.hqd.ch03.v13.io.support.DefaultResourceLoader;
import com.hqd.ch03.v13.registry.BeanDefinitionRegistry;
import com.hqd.ch03.v13.registry.support.DefaultSingletonBeanRegistry;
import com.hqd.ch03.v13.registry.support.SimpleBeanDefinitionRegistry;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.beans.PropertyEditor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class SpringImitationV13 extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>();
protected BeanDefinitionRegistry beanDefinitionRegistry = new SimpleBeanDefinitionRegistry();
/**
* 单例缓存
*/
protected Map<String, Scope> scopeCache = new HashMap<>();
/**
* 资源加载器
*/
protected ResourceLoader resourceLoader = new DefaultResourceLoader();
/**
* bean初始化回调接口
*/
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public static boolean isFactoryDereference(String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
@Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
customEditors.put(requiredType, propertyEditorClass);
}
/**
* 处理传入的name,去除&开头
*
* @param name
* @return
*/
protected String transformedBeanName(String name) {
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
String beanName = name;
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
}
/**
* 区分正常bean还是FactoryBean
*
* @param obj
* @param name
* @param beanName
* @param bd
* @return
*/
protected Object getObjectForBeanInstance(Object obj, String name, String beanName, BeanDefinition bd) {
if (isFactoryDereference(name)) {
if (!(obj instanceof FactoryBean)) {
throw new RuntimeException(String.format("%s 未实现FactoryBean接口", beanName));
}
return obj;
}
if (obj instanceof FactoryBean) {
return ((FactoryBean) obj).getObject();
}
return obj;
}
private void populateBean(BeanWrapper beanWrapper, BeanDefinition bd) {
try {
MutablePropertyValues properties = bd.getProperties();
if (properties != null) {
properties.getProperties().forEach(propertyValue -> {
boolean isRef = propertyValue.isRef();
Object value = propertyValue.getValue();
if (isRef) {
value = getBean((String) value);
}
try {
beanWrapper.setPropertyValue(propertyValue.getName(), value, isRef);
//BeanUtils.setProperty(bean, propertyValue.getName(), value);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object createBean(BeanDefinition bd, String beanName) {
try {
Object instance = null;
if (bd.isSingleton()) {//单例
instance = getSingleton(beanName);
if (instance == null) {
instance = doCreate(bd, beanName);
}
addSingleton(beanName, instance);
} else if (bd.isPrototype()) {//多例
instance = doCreate(bd, beanName);
} else {//自定义作用域
String scopeName = bd.getScope();
Scope scope = scopeCache.get(scopeName);
if (scope == null) {
throw new RuntimeException(String.format("[%s]未注册scope", scopeName));
}
instance = scope.get(beanName, () -> doCreate(bd, beanName));
}
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 设置Aware接口
*
* @param beanName
* @param bean
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(resourceLoader);
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
}
}
protected Object doCreate(BeanDefinition bd, String beanName) {
String beanClass = bd.getBeanClass();
try {
Object instance = Class.forName(beanClass).getConstructor().newInstance();
BeanWrapper beanWrapper = new BeanWrapperImpl(instance);
initBeanWrapper(beanWrapper);
addSingletonFactory(beanName, () -> beanWrapper.getWrappedInstance());
/**
* 执行init有可能对象发生变化
*/
Object exposedObject = instance;
populateBean(beanWrapper, bd);
exposedObject = initializeBean(beanName, exposedObject, bd);
return exposedObject;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected Object initializeBean(String beanName, Object bean, BeanDefinition bd) {
if (bean != null) {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
//调用BeanPostProcessor前置方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用init方法
invokeInitMethods(wrappedBean, bd);
//调用BeanPostProcessor后置方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
/**
* 执行init方法
*
* @param wrappedBean
* @param bd
*/
protected void invokeInitMethods(Object wrappedBean, BeanDefinition bd) {
String initMethodName = bd.getInitMethodName();
if (StringUtils.isBlank(initMethodName)) {
return;
}
try {
Method initMethod = wrappedBean.getClass().getDeclaredMethod(initMethodName);
initMethod.invoke(wrappedBean);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 执行BeanPostProcessor前置方法
*
* @param existingBean
* @param beanName
* @return
*/
protected Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
/**
* 执行BeanPostProcessor后置方法
*
* @param existingBean
* @param beanName
* @return
*/
protected Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return beanPostProcessors;
}
@Override
public void addBeanPostProcessor(BeanPostProcessor postProcessor) {
if (postProcessor != null) {
synchronized (beanPostProcessors) {
beanPostProcessors.remove(postProcessor);
beanPostProcessors.add(postProcessor);
}
}
}
protected void initBeanWrapper(BeanWrapper bw) {
/**
* 注册自定义类型转换器
*
*/
registerCustomEditors(bw);
}
/**
* 是否应该区分全局转换器和局部转换器
* 全局为Factory级别,局部为Bean级别
*
* @param bw
*/
protected void registerCustomEditors(BeanWrapper bw) {
if (MapUtils.isNotEmpty(customEditors)) {
customEditors.forEach((key, val) -> {
try {
bw.registerCustomEditor(key, val.getConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@Override
public void registerScope(String scopeName, Scope scope) {
if (StringUtils.isNotBlank(scopeName) && scope != null) {
scopeCache.put(scopeName, scope);
}
}
@Override
public <T> T getBean(String name, Class<T> clazz) {
return (T) doGetBean(name);
}
@Override
public Object getBean(String name) {
return doGetBean(name);
}
protected Object doGetBean(String name) {
String beanName = transformedBeanName(name);
BeanDefinition bd = beanDefinitionRegistry.getBeanDefinition(beanName);
Object bean = createBean(bd, beanName);
bean = getObjectForBeanInstance(bean, name, beanName, bd);
return bean;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
O几把K,接下来,又是测试的时间了。A君 先定义Car对象,代码如下:
import lombok.Data;
@Data
public class Car {
private String brand;
private double price;
public void init() {
System.out.println("初始化");
}
}
再定一个CarBeanPostProcessor,再car初始化之后做一内内修改,代码如下:
import com.hqd.ch03.bean.Car;
import com.hqd.ch03.v13.config.BeanPostProcessor;
import org.apache.commons.lang3.StringUtils;
public class CarBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println("初始化前");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (StringUtils.equals(beanName, "car") && bean instanceof Car) {
Car car = (Car) bean;
System.out.println("修改前:" + car);
car.setBrand("帕拉梅拉");
car.setPrice(9999.99);
System.out.println("修改后:" + car);
}
System.out.println("初始化后");
return bean;
}
}
xml定义没什么大变化,如下:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car" class="com.hqd.ch03.bean.Car" init-method="init">
<property name="brand" value="1.11"/>
<property name="price" value="1.11"/>
</bean>
</beans>
测试代码如下:
@Test
public void v13() {
System.out.println("############# 第十三版:BeanPostProcessor接口 #############");
SpringImitationV13 beanFactory = new SpringImitationV13Xml("classpath:v13/bean.xml");
beanFactory.addBeanPostProcessor(new CarBeanPostProcessor());
Car car = beanFactory.getBean("car", Car.class);
System.out.println("加载标签对象:" + car);
car = beanFactory.getBean("car", Car.class);
System.out.println("加载标签对象:" + car);
}
测试结果如下:
结果并没有出现什么意外,和预想的一样。意味着A君的第二版拓展改造也就宣告完成了,这次拓展bean初始化前后置增强
第十四版 监听容器的动作:事件监听
第二版改造完毕后,还剩一部分重要的拓展——事件监听。说到事件监听,就不得不先说观察者模式了
观察者模式
对于观察者模式,A君还是有所了解的。曾经,A君追过明星ikun,是ikun的狂热粉丝,喜欢他的一切,关注他的一切。只要ikun一发动态,A君 就马上过去点赞评论。此时,A君就是观察者,ikun就是被观察者。基于自身经历,A君做了个小小的demo,先是明星,一个被观察的对象:GieGie,如下:
import lombok.Data;
import java.util.Observable;
@Data
public class GieGie extends Observable {
private String name = "ikun";
private String msg;
public void doSomething(String msg) {
this.msg = msg;
System.out.println(String.format("GieGie:%s 正在 '%s'", name, msg));
setChanged();
notifyObservers();
}
}
接着是ikun的两个粉丝(观察者),先是粉丝1——张三,代码如下:
import lombok.Data;
import java.util.Observable;
import java.util.Observer;
@Data
public class Fans1 implements Observer {
private String name = "张三";
@Override
public void update(Observable o, Object obj) {
if (o instanceof GieGie) {
GieGie gg = (GieGie) o;
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,马上过去点赞", name,
gg.getName(), gg.getMsg()));
}
}
}
粉丝2——李四,代码如下:
import lombok.Data;
import java.util.Observable;
import java.util.Observer;
@Data
public class Fans2 implements Observer {
private String name = "李四";
@Override
public void update(Observable o, Object obj) {
if (o instanceof GieGie) {
GieGie gg = (GieGie) o;
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,不感兴趣", name,
gg.getName(), gg.getMsg()));
}
}
}
张三、李四都去关注了ikun,ikun一有动态,他们就能立即知道,代码如下:
@Test
public void observe() {
GieGie gg = new GieGie();
Fans1 fans1 = new Fans1();
Fans2 fans2 = new Fans2();
gg.addObserver(fans1);
gg.addObserver(fans2);
gg.doSomething("发布了新专辑");
System.out.println("######################################");
gg.doSomething("爆出了绯闻");
}
测试结果如下:
张三、李四都第一时间收到ikun的动态,并且做出了回应,一如当时的A君
事件监听
随着A君年纪的增长,对ikun已经没有那么狂热了,对ikun的绯闻什么的已经没兴趣了,只想看ikun的相关视频。于是乎,代码也需要跟着改变了,需要对GieGie发布的事件做一个区分,先为GieGie定义一个专门的事件,如下:
import com.hqd.test.observe.GieGie;
import java.util.EventObject;
public class GieGieEvent extends EventObject {
public GieGieEvent(GieGie source) {
super(source);
}
@Override
public GieGie getSource() {
return (GieGie) super.getSource();
}
}
再来区分发布的事情做个分类,绯闻事件如下:
import com.hqd.test.observe.GieGie;
public class ScandalEvent extends GieGieEvent {
public ScandalEvent(GieGie source) {
super(source);
}
}
发布专辑事件如下:
import com.hqd.test.observe.GieGie;
/**
* 发布专辑事件
*/
public class ReleaseAlbumsEvent extends GieGieEvent {
public ReleaseAlbumsEvent(GieGie source) {
super(source);
}
}
有了事件后,还需要一个发布事件类,用来发布GieGie的各种事件。GieGieEventPublisher代码如下:
import com.hqd.ch03.v14.utils.GenericClassUtils;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class GieGieEventPublisher {
private Set<GieGieListener> listeners = new LinkedHashSet<>();
/**
* 发布事件
*
* @param event
*/
public void publishEvent(GieGieEvent event) {
List<GieGieListener> fans = getFans(event);
for (GieGieListener listener : fans) {
listener.doSomething(event);
}
}
private List<GieGieListener> getFans(GieGieEvent event) {
Class eventClass = event.getClass();
List<GieGieListener> fans = new ArrayList<>(listeners.size());
for (GieGieListener listener : listeners) {
//查找接口泛型
Class<?> typeArgument = GenericClassUtils
.getInterfaceActualTypeArgument(listener.getClass(), GieGieListener.class, 0);
if (typeArgument.isAssignableFrom(eventClass)) {
fans.add(listener);
}
}
return fans;
}
public void addListener(GieGieListener listener) {
listeners.add(listener);
}
public void removeListener(GieGieListener listener) {
listeners.remove(listener);
}
}
GieGie还是那个GieGie,想要了解他,还是需要关注他,关注他之后,才能知道他发布的事件。所以定义GieGieListener接口,代码如下:
import java.util.EventListener;
public interface GieGieListener<E extends GieGieEvent> extends EventListener {
void doSomething(E e);
}
接着,分别有三位粉丝对ikun进行了关注,粉丝1——王五:“只喜欢吃瓜,就只关注了绯闻事件”,代码如下:
import com.hqd.test.observe.GieGie;
public class FansListener1 implements GieGieListener<ScandalEvent> {
private String name = "王五";
@Override
public void doSomething(ScandalEvent event) {
GieGie gg = event.getSource();
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,马上去吃瓜", name,
gg.getName(), gg.getMsg()));
}
}
粉丝2——赵六:“只喜欢听歌,对绯闻没什么兴趣”,代码如下:
import com.hqd.test.observe.GieGie;
public class FansListener2 implements GieGieListener<ReleaseAlbumsEvent> {
private String name = "赵六";
@Override
public void doSomething(ReleaseAlbumsEvent event) {
GieGie gg = event.getSource();
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,马上购买", name,
gg.getName(), gg.getMsg()));
}
}
粉丝3——孙七:“喜欢ikun的一切,时刻关注这ikun的一举一动”,代码如下:
import com.hqd.test.observe.GieGie;
public class FansListener3 implements GieGieListener<GieGieEvent> {
private String name = "孙七";
@Override
public void doSomething(GieGieEvent event) {
GieGie gg = event.getSource();
if (event instanceof ScandalEvent) {
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,马上去吃瓜", name,
gg.getName(), gg.getMsg()));
} else if (event instanceof ReleaseAlbumsEvent) {
System.out.println(String.format("粉丝'%s'知道了GieGie'%s'正在 %s,马上去购买", name,
gg.getName(), gg.getMsg()));
}
}
}
接下来,ikun开始发布动态了,代码如下:
@Test
public void event() {
GieGie gieGie = new GieGie();
GieGieEventPublisher publisher = new GieGieEventPublisher();
//添加粉丝
FansListener1 fans1 = new FansListener1();
FansListener2 fans2 = new FansListener2();
FansListener3 fans3 = new FansListener3();
publisher.addListener(fans1);
publisher.addListener(fans2);
publisher.addListener(fans3);
gieGie.setMsg("发布专辑");
publisher.publishEvent(new ReleaseAlbumsEvent(gieGie));
System.out.println("######################################");
gieGie.setMsg("爆出绯闻");
publisher.publishEvent(new ScandalEvent(gieGie));
}
运行结果如下:
可以看到,ikun发布专辑时,只在乎吃瓜的王五并没有收到消息,只有喜欢听歌的赵六和喜欢ikun一切有收到通知。而当ikun爆出绯闻时,只喜欢听歌的赵六没有收到任何消息,喜欢吃瓜的王五和喜欢ikun一切的孙七收到了通知
经过上边的例子,A君已经大体明白了。开始着手进行改造,给容器加上事件监听。首先,A君定义了一个工厂的总事件:BeanFactoryEvent,代码如下:
import com.hqd.ch03.v14.factory.BeanFactory;
import java.util.EventObject;
/**
* 工厂事件
*/
public abstract class BeanFactoryEvent extends EventObject {
public BeanFactoryEvent(BeanFactory source) {
super(source);
}
@Override
public BeanFactory getSource() {
return (BeanFactory) super.getSource();
}
}
再细分成启动事件和结束事件,启动事件:BeanFactoryStartedEvent,代码如下:
import com.hqd.ch03.v14.factory.BeanFactory;
public class BeanFactoryStartedEvent extends BeanFactoryEvent {
public BeanFactoryStartedEvent(BeanFactory source) {
super(source);
}
}
结束事件:BeanFactoryEndEvent,代码如下:
import com.hqd.ch03.v14.factory.BeanFactory;
public class BeanFactoryEndEvent extends BeanFactoryEvent {
public BeanFactoryEndEvent(BeanFactory source) {
super(source);
}
}
接着,定义个监听接口,留给对事件感兴趣的人实现,如下:
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
import java.util.EventListener;
/**
* 事件监听者
*
* @param <E>
*/
public interface BeanFactoryListener<E extends BeanFactoryEvent> extends EventListener {
/**
* 触发事件
*
* @param event
*/
void onEvent(E event);
}
还需要个监听器管理器,用以添加、删除、寻找对应事件监听等操作,BeanFactoryEventMulticaster接口代码如下:
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
/**
* 监听器管理器
*/
public interface BeanFactoryEventMulticaster {
/**
* 添加监听器
*
* @param listener
*/
void addBeanFactoryListener(BeanFactoryListener<?> listener);
/**
* 添加监听器
*
* @param listenerBeanName 容器中存在的bean
*/
void addBeanFactoryListenerBean(String listenerBeanName);
/**
* 删除监听器
*
* @param listener
*/
void removeBeanFactoryListener(BeanFactoryListener<?> listener);
/**
* 删除监听器
*
* @param listenerBeanName 容器中存在的bean
*/
void removeBeanFactoryListenerBean(String listenerBeanName);
/**
* 触发监听器
*
* @param event
*/
void multicastEvent(BeanFactoryEvent event);
}
提供个监听器管理器的默认实现,这里查找监听事件需要注意一下,要根据事件Class类型去匹配监听者的泛型Class,匹配上了,就是对应的监听器了。SimpleBeanFactoryEventMulticaster代码如下:
import com.hqd.ch03.v14.factory.BeanFactory;
import com.hqd.ch03.v14.listener.BeanFactoryEventMulticaster;
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
import com.hqd.ch03.v14.utils.GenericClassUtils;
import org.apache.commons.collections.CollectionUtils;
import java.util.*;
/**
* 事件广播器默认处理
*/
public class SimpleBeanFactoryEventMulticaster implements BeanFactoryEventMulticaster {
private BeanFactory beanFactory;
private Set<BeanFactoryListener<?>> listeners = new LinkedHashSet<>();
public SimpleBeanFactoryEventMulticaster(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void addBeanFactoryListener(BeanFactoryListener<?> listener) {
listeners.add(listener);
}
@Override
public void addBeanFactoryListenerBean(String listenerBeanName) {
Object bean = this.beanFactory.getBean(listenerBeanName);
if (bean != null && bean instanceof BeanFactoryListener) {
listeners.add((BeanFactoryListener<?>) bean);
}
}
@Override
public void removeBeanFactoryListener(BeanFactoryListener<?> listener) {
listeners.remove(listener);
}
@Override
public void removeBeanFactoryListenerBean(String listenerBeanName) {
Object bean = this.beanFactory.getBean(listenerBeanName);
if (bean != null && bean instanceof BeanFactoryListener) {
listeners.remove((BeanFactoryListener<?>) bean);
}
}
@Override
public void multicastEvent(BeanFactoryEvent event) {
Collection<BeanFactoryListener> beanFactoryListeners = getBeanFactoryListeners(event);
if (CollectionUtils.isNotEmpty(beanFactoryListeners)) {
beanFactoryListeners.forEach(listener -> {
listener.onEvent(event);
});
}
}
/**
* 获取匹配的监听器
*
* @return
*/
protected Collection<BeanFactoryListener> getBeanFactoryListeners(BeanFactoryEvent event) {
if (CollectionUtils.isEmpty(this.listeners)) {
return null;
}
List<BeanFactoryListener> eventListeners = new ArrayList<>(this.listeners.size());
this.listeners.forEach(listener -> {
Class<?> typeArgument = GenericClassUtils.getInterfaceActualTypeArgument(listener.getClass(),
BeanFactoryListener.class, 0);
if (typeArgument.isAssignableFrom(event.getClass())) {
eventListeners.add(listener);
}
});
return eventListeners;
}
}
还需要一个事件发布器——BeanFactoryEventPublisher,代码如下:
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
@FunctionalInterface
public interface BeanFactoryEventPublisher {
/**
* 发布事件
*
* @param event
*/
void publishEvent(BeanFactoryEvent event);
}
对于BeanFactoryEventPublisher,这块着实困扰了A君许久,如果只是发布事件,明明BeanFactoryEventMulticaster就能实现了,为什么特地还要多加个所谓的事件发布器呢?非要说的话,应该是职责不一样,BeanFactoryEventPublisher只负责发布,并不具备对事件监听者的操作。拿之前的ikun为例:ikun能发布事件,具体怎么找到关注该事件的粉丝,怎么发布的,ikun并不关心。还有ikun也没法决定粉丝关不关注他,换句话说,粉丝关注与否,不应该经过ikun。而BeanFactoryEventMulticaster确是真正的管理者,他能找到对事件感兴趣的粉丝发送消息,粉丝关注取关也是通过它。门面模式?
ConfigurableBeanFactory现在还不具备添加监听者的能力,再给ConfigurableBeanFactory添加个方法,改造如下:
完整代码:
import com.hqd.ch03.v14.config.BeanPostProcessor;
import com.hqd.ch03.v14.config.Scope;
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import java.beans.PropertyEditor;
public interface ConfigurableBeanFactory extends BeanFactory {
/**
* 单例
*/
String SCOPE_SINGLETON = "singleton";
/**
* 多利
*/
String SCOPE_PROTOTYPE = "prototype";
void registerScope(String scopeName, Scope scope);
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
void addBeanFactoryListener(BeanFactoryListener<?> listener);
}
接着对SpringImitation进行改造,SpringImitation需要拥有发布事件的功能,所以需要实现BeanFactoryEventPublisher接口,改造如下:
完整代码:
import com.hqd.ch03.v14.aware.*;
import com.hqd.ch03.v14.beans.BeanWrapper;
import com.hqd.ch03.v14.beans.BeanWrapperImpl;
import com.hqd.ch03.v14.config.BeanDefinition;
import com.hqd.ch03.v14.config.BeanPostProcessor;
import com.hqd.ch03.v14.config.MutablePropertyValues;
import com.hqd.ch03.v14.config.Scope;
import com.hqd.ch03.v14.factory.BeanFactory;
import com.hqd.ch03.v14.factory.ConfigurableBeanFactory;
import com.hqd.ch03.v14.factory.FactoryBean;
import com.hqd.ch03.v14.io.ResourceLoader;
import com.hqd.ch03.v14.io.support.DefaultResourceLoader;
import com.hqd.ch03.v14.listener.BeanFactoryEventMulticaster;
import com.hqd.ch03.v14.listener.BeanFactoryEventPublisher;
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
import com.hqd.ch03.v14.listener.support.SimpleBeanFactoryEventMulticaster;
import com.hqd.ch03.v14.registry.BeanDefinitionRegistry;
import com.hqd.ch03.v14.registry.support.DefaultSingletonBeanRegistry;
import com.hqd.ch03.v14.registry.support.SimpleBeanDefinitionRegistry;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import java.beans.PropertyEditor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class SpringImitationV14 extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory, BeanFactoryEventPublisher {
/**
* 自定义类型转换器
*/
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>();
/**
* 事件广播器
*/
protected BeanFactoryEventMulticaster multicaster = new SimpleBeanFactoryEventMulticaster(this);
protected BeanDefinitionRegistry beanDefinitionRegistry = new SimpleBeanDefinitionRegistry();
/**
* 单例缓存
*/
protected Map<String, Scope> scopeCache = new HashMap<>();
/**
* 资源加载器
*/
protected ResourceLoader resourceLoader = new DefaultResourceLoader();
/**
* bean初始化回调接口
*/
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();
public static boolean isFactoryDereference(String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
@Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
customEditors.put(requiredType, propertyEditorClass);
}
@Override
public void publishEvent(BeanFactoryEvent event) {
doPublishEvent(event);
}
protected void doPublishEvent(BeanFactoryEvent event) {
multicaster.multicastEvent(event);
}
@Override
public void addBeanFactoryListener(BeanFactoryListener<?> listener) {
multicaster.addBeanFactoryListener(listener);
}
/**
* 处理传入的name,去除&开头
*
* @param name
* @return
*/
protected String transformedBeanName(String name) {
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
String beanName = name;
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
}
/**
* 区分正常bean还是FactoryBean
*
* @param obj
* @param name
* @param beanName
* @param bd
* @return
*/
protected Object getObjectForBeanInstance(Object obj, String name, String beanName, BeanDefinition bd) {
if (isFactoryDereference(name)) {
if (!(obj instanceof FactoryBean)) {
throw new RuntimeException(String.format("%s 未实现FactoryBean接口", beanName));
}
return obj;
}
if (obj instanceof FactoryBean) {
return ((FactoryBean) obj).getObject();
}
return obj;
}
private void populateBean(BeanWrapper beanWrapper, BeanDefinition bd) {
try {
MutablePropertyValues properties = bd.getProperties();
if (properties != null) {
properties.getProperties().forEach(propertyValue -> {
boolean isRef = propertyValue.isRef();
Object value = propertyValue.getValue();
if (isRef) {
value = getBean((String) value);
}
try {
beanWrapper.setPropertyValue(propertyValue.getName(), value, isRef);
//BeanUtils.setProperty(bean, propertyValue.getName(), value);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Object createBean(BeanDefinition bd, String beanName) {
try {
Object instance = null;
if (bd.isSingleton()) {//单例
instance = getSingleton(beanName);
if (instance == null) {
instance = doCreate(bd, beanName);
}
addSingleton(beanName, instance);
} else if (bd.isPrototype()) {//多例
instance = doCreate(bd, beanName);
} else {//自定义作用域
String scopeName = bd.getScope();
Scope scope = scopeCache.get(scopeName);
if (scope == null) {
throw new RuntimeException(String.format("[%s]未注册scope", scopeName));
}
instance = scope.get(beanName, () -> doCreate(bd, beanName));
}
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 设置Aware接口
*
* @param beanName
* @param bean
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(resourceLoader);
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
if (bean instanceof BeanFactoryEventPublisherAware) {
((BeanFactoryEventPublisherAware) bean).setBeanFactoryEventPublisher(this);
}
}
}
protected Object doCreate(BeanDefinition bd, String beanName) {
String beanClass = bd.getBeanClass();
try {
Object instance = Class.forName(beanClass).getConstructor().newInstance();
BeanWrapper beanWrapper = new BeanWrapperImpl(instance);
initBeanWrapper(beanWrapper);
addSingletonFactory(beanName, () -> beanWrapper.getWrappedInstance());
/**
* 执行init有可能对象发生变化
*/
Object exposedObject = instance;
populateBean(beanWrapper, bd);
exposedObject = initializeBean(beanName, exposedObject, bd);
return exposedObject;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected Object initializeBean(String beanName, Object bean, BeanDefinition bd) {
if (bean != null) {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
//调用init方法
invokeInitMethods(wrappedBean, bd);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
/**
* 执行init方法
*
* @param wrappedBean
* @param bd
*/
protected void invokeInitMethods(Object wrappedBean, BeanDefinition bd) {
String initMethodName = bd.getInitMethodName();
if (StringUtils.isBlank(initMethodName)) {
return;
}
try {
Method initMethod = wrappedBean.getClass().getDeclaredMethod(initMethodName);
initMethod.invoke(wrappedBean);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 执行BeanPostProcessor前置方法
*
* @param existingBean
* @param beanName
* @return
*/
protected Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
/**
* 执行BeanPostProcessor后置方法
*
* @param existingBean
* @param beanName
* @return
*/
protected Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return beanPostProcessors;
}
@Override
public void addBeanPostProcessor(BeanPostProcessor postProcessor) {
if (postProcessor != null) {
synchronized (beanPostProcessors) {
beanPostProcessors.remove(postProcessor);
beanPostProcessors.add(postProcessor);
}
}
}
protected void initBeanWrapper(BeanWrapper bw) {
/**
* 注册自定义类型转换器
*
*/
registerCustomEditors(bw);
}
/**
* 是否应该区分全局转换器和局部转换器
* 全局为Factory级别,局部为Bean级别
*
* @param bw
*/
protected void registerCustomEditors(BeanWrapper bw) {
if (MapUtils.isNotEmpty(customEditors)) {
customEditors.forEach((key, val) -> {
try {
bw.registerCustomEditor(key, val.getConstructor().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
@Override
public void registerScope(String scopeName, Scope scope) {
if (StringUtils.isNotBlank(scopeName) && scope != null) {
scopeCache.put(scopeName, scope);
}
}
@Override
public <T> T getBean(String name, Class<T> clazz) {
return (T) doGetBean(name);
}
@Override
public Object getBean(String name) {
return doGetBean(name);
}
protected Object doGetBean(String name) {
String beanName = transformedBeanName(name);
BeanDefinition bd = beanDefinitionRegistry.getBeanDefinition(beanName);
Object bean = createBean(bd, beanName);
bean = getObjectForBeanInstance(bean, name, beanName, bd);
return bean;
}
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
接着,就由SpringImitationXml进行发布事件,改造如下:
registerListeners方法如下:
getBeanNamesForType方法如下:
完整代码:
import com.hqd.ch03.v14.config.BeanDefinition;
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import com.hqd.ch03.v14.listener.event.BeanFactoryEndEvent;
import com.hqd.ch03.v14.listener.event.BeanFactoryStartedEvent;
import com.hqd.ch03.v14.reader.support.XmlBeanDefinitionReader;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ClassUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class SpringImitationV14Xml extends SpringImitationV14 {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry);
public SpringImitationV14Xml(String location) {
this.reader.loadBeanDefinition(resourceLoader.getResource(location));
registerListeners();
publishEvent(new BeanFactoryStartedEvent(this));
//doSomething
publishEvent(new BeanFactoryEndEvent(this));
}
protected void registerListeners() {
List<String> listenerBeanNames = getBeanNamesForType(BeanFactoryListener.class);
if (CollectionUtils.isNotEmpty(listenerBeanNames)) {
for (String listenerBeanName : listenerBeanNames) {
addBeanFactoryListener(getBean(listenerBeanName, BeanFactoryListener.class));
}
}
}
protected List<String> getBeanNamesForType(Class<?> beanClass) {
String[] beanDefinitionNames = beanDefinitionRegistry.getBeanDefinitionNames();
List<String> listenerNames = new ArrayList<>(beanDefinitionNames.length);
Arrays.stream(beanDefinitionNames).forEach(beanName -> {
BeanDefinition beanDefinition = beanDefinitionRegistry.getBeanDefinition(beanName);
try {
if (ClassUtils.isAssignable(ClassUtils.getClass(beanDefinition.getBeanClass()), beanClass)) {
listenerNames.add(beanName);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
});
return listenerNames;
}
}
又到了测试的环节了,先添加个XmlFactory启动监听,代码如下:
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import com.hqd.ch03.v14.listener.event.BeanFactoryStartedEvent;
public class XmlFactoryStartedListener implements BeanFactoryListener<BeanFactoryStartedEvent> {
@Override
public void onEvent(BeanFactoryStartedEvent event) {
System.out.println("xml工厂开始启动");
}
}
再添加个XmlFactory结束监听,代码如下:
import com.hqd.ch03.v14.listener.BeanFactoryListener;
import com.hqd.ch03.v14.listener.event.BeanFactoryEndEvent;
public class XmlFactoryEndListener implements BeanFactoryListener<BeanFactoryEndEvent> {
@Override
public void onEvent(BeanFactoryEndEvent event) {
System.out.println("xml工厂启动完成 ");
}
}
添加完系统事件监听,再添加个自定义事件,如下:
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
public class TaskFinishEvent extends BeanFactoryEvent {
public TaskFinishEvent(Object source) {
super(source);
}
}
自定义事件监听器如下:
import com.hqd.ch03.v14.listener.BeanFactoryListener;
public class MailTaskFinishListener implements BeanFactoryListener<TaskFinishEvent> {
private String email = "harvey@163.com";
@Override
public void onEvent(TaskFinishEvent event) {
System.out.println("Send Email to " + email + " Task:" + event.getSource());
}
}
自定义事件发布器如下:
import com.hqd.ch03.v14.aware.BeanFactoryEventPublisherAware;
import com.hqd.ch03.v14.listener.BeanFactoryEventPublisher;
import com.hqd.ch03.v14.listener.event.BeanFactoryEvent;
public class EventPublisher implements BeanFactoryEventPublisherAware {
private BeanFactoryEventPublisher eventPublisher;
//发布事件
public void publishEvent(BeanFactoryEvent event) {
eventPublisher.publishEvent(event);
}
@Override
public void setBeanFactoryEventPublisher(BeanFactoryEventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
}
xml配置如下:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="listener" class="com.hqd.ch03.test.event.MailTaskFinishListener"/>
<bean id="endListener" class="com.hqd.ch03.test.event.XmlFactoryEndListener"/>
<bean id="startedListener" class="com.hqd.ch03.test.event.XmlFactoryStartedListener"/>
<bean id="publisher" class="com.hqd.ch03.test.event.EventPublisher"/>
</beans>
测试代码如下:
@Test
public void v14() {
System.out.println("############# 第十四版:监听器 #############");
SpringImitationV14 beanFactory = new SpringImitationV14Xml("classpath:v14/bean.xml");
EventPublisher publisher = beanFactory.getBean("publisher", EventPublisher.class);
//事件源
Task source = new Task("用户统计人物");
TaskFinishEvent event = new TaskFinishEvent(source);
publisher.publishEvent(event);
}
测试结果如下:
可以看到,无论是系统事件,还是自定义事件都成功触发
改到这里,老大终于没有再说什么了,A君终于是解脱了。自己动手写IOC容器,也算告一段落了。托老大的服,A君对Spring的理解也达到了前所未有的高度
总结
历经千辛万苦,项目终于是结束了。A君也是大有所获,不知道对大家是否有所帮助。实际上,看过spring源码的小伙伴们都知道,说是自己动手实现,其实就是spring的相关代码。只不过是站在一个容器开发者的角度去揣测spring为什么这么实现,有什么深意?像极了以前做阅读理解时候的样子。当然了,以上的内容只是一家之言,属于个人理解,如果有理解错误、或者是描述错误的地方,也欢迎大家指出(✪ω✪)