Spring IOC AOP的手写实现(二)
IOC的实现
1.1 BeanFactory的生命流程
- BeanFactory加载Bean配置文件,将读到的Bean配置封装成BeanDefinition对象
- 将封装好的BeanDefinition对象注册到BeanDefinition容器中
- 注册BeanPostProcessor相关实现类到BeanPostProcessor容器中
- BeanFactory进入就绪状态
- 外部调用BeanFactory的getBean(String name)方法,BeanFactory着手实例化相应的bean
- 重复3、4,直至程序退出,BeanFactory被销毁
1.2 BeanDefinition及其他一些类的介绍
-
BeanDefinition:作用是根据Bean的配置信息生产成本相应的Bean详情对象,如果把Bean比喻为电脑 ,那么BeanDefinition就是电脑的配置清单,可以透过电脑看到电脑的详细配置。
-
BeanReference:保存bean配置中ref属性对应的值,在后续BeanFactory实例化bean时,会根据BeanReference保存的值去实例化bean所依赖的其他bean。
-
PropertyValues和PropertyValue
-
PropertyValue:name、value字段记录bean标签中的属性值
-
PropertyValues:虽然只是上面的复数形式,也就是相当于一个属性的List集合,那为什么不直接使用List而要定义一个新的类呢?——为了获得一定的控制权
比如:定义这个PropertyValues类把对属性的列表加入操作封装起来,内部可以添加一些其他的处理,之后再调用List的add方法
-
1.3 xml的解析
BeanFactory初始化时,会根据传入的xml配置文件路径来加载配置文件,然而BeanFactory值需要管理容器中的bean就可以了,加载和解析配置文件的任务由BeanDefinitionReader的实现类XmlBeanDefinitionReader去做就可以了
- 将xml配置文件加载到内存中
- 获取根标签下的所有标签
- 遍历获取到的标签列表,取出id、class属性
- 创建BeanDefinition对象,并将刚刚读取到的id、class属性保存到对象中
- 遍历标签下的标签,读取属性值并保存到对象中
- 将<id,BeanDefinition>键值对缓存在Map中,留在后面使用
- 重复3、4、5、6步,直至解析结束
1.4注册BeanPostProcessor
BeanPostProcessor是Spring对外拓展的接口之一,主要用途:提供一个机会,让开发人员能够插手bean的实例化过程。我们可以在bean实例化的过程中对bean进行一些处理,比如AOP织入相关bean中。
康康BeanFactory如何注册BeanPostProcessor相关实现类的
XmlBeanDefinitionReader在完成解析工作后,BeanFactory会将键值对<id,BeanDefinition>注册到自己的beanDefinitionMap中。BeanFactory注册好BeanDefinition后,就立即开始注册BeanPostProcessor的相关实现类。这个过程
- 根据BeanDefinition记录的信息,寻找所有实现了BeanPostProcessor的接口的类
- 实例化BeanPostProcessor接口的实现类
- 将实例化好的对象放入List中
- 重复2、3步,直至所有的实现类完成注册
1.5 getBean过程解析
在完成xml的解析,BeanDefinition的注册,以及BeanPostProcessor的注册后,BeanFactory的初始化工作就算是结束了,此时BeanFactory处于就绪状态,等待外部程序的调用。它具有延迟实例化bean的特性,也就是等外部程序需要的时候,才实例化。这样做
- 提高BeanFactory的初始化速度
- 节省内存资源
看看Spring bean实例化过程 :
我们仿写的过程中简化流程:
- 实例化bean对象
- 设置对象属性: 将配置文件中配置的属性填充到刚刚创建的 bean 对象中
- 检查Aware相关接口并设置相关依赖
- BeanPostProcessor前置处理 postProcessBeforeInitialization(Object bean, String beanName)
- BeanPostProcessor后置处理 postProcessAfterInitialization(Object bean, String beanName)
- 使用中
先看相关的接口:
BeanFactory接口:
/**
* 工厂接口
*/
public interface BeanFactory {
Object getBean(String beanId) throws Exception;
}
BeanFactoryAware接口:设置为别的BeanFactory
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws Exception;
}
BeanDefinitionReader接口:把配置文件读到BeanDefinition中去
public interface BeanDefinitionReader {
void loadBeanDefinitions(String location) throws FileNotFoundException, Exception;
}
BeanPostProcessor 插手实例化的接口:
public interface BeanPostProcessor {
/**
* 前置处理
*/
Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception;
/**
* 后置处理
*/
Object postProcessAfterInitialization(Object bean, String beanName) throws Exception;
}
BeanDefinition类:提供了相应属性值和get、set方法
public class BeanDefinition {
private Object bean;
private Class beanClass;
private String beanClassName;
private PropertyValues propertyValues = new PropertyValues();
public BeanDefinition() {
}
public void setBean(Object bean) {
this.bean = bean;
}
public Class getBeanClass() {
return beanClass;
}
public void setBeanClass(Class beanClass) {
this.beanClass = beanClass;
}
public String getBeanClassName() {
return beanClassName;
}
public void setBeanClassName(String beanClassName) {
this.beanClassName = beanClassName;
try {
this.beanClass = Class.forName(beanClassName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public Object getBean() {
return bean;
}
public PropertyValues getPropertyValues() {
return propertyValues;
}
public void setPropertyValues(PropertyValues propertyValues) {
this.propertyValues = propertyValues;
}
}
BeanReference类:bean的引用
public class BeanReference {
private String name;
private Object bean;
public BeanReference(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object getBean() {
return bean;
}
public void setBean(Object bean) {
this.bean = bean;
}
}
PropertyValue、PropertyValues:属性值
public class PropertyValue {
private final String name;
private final Object value;
public PropertyValue(String name, Object value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public Object getValue() {
return value;
}
}
public class PropertyValues {
private final List<PropertyValue> propertyValueList = new ArrayList<PropertyValue>();
public void addPropertyValue(PropertyValue pv) {
// 在这里可以对参数值 pv 做一些处理,如果直接使用 List,则就不行了
this.propertyValueList.add(pv);
}
public List<PropertyValue> getPropertyValues() {
return this.propertyValueList;
}
}
XmlBeanDefinitionReader: 解析 xml
public class XmlBeanDefinitionReader implements BeanDefinitionReader {
private Map<String,BeanDefinition> registry;
public XmlBeanDefinitionReader() {
registry = new HashMap<>();//实例化的时候才加载map
}
/**
* 读入配置文件,加载BeanDefinitions
*/
@Override
public void loadBeanDefinitions(String location) throws Exception {
InputStream inputStream = new FileInputStream(location);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = factory.newDocumentBuilder();
Document doc = docBuilder.parse(inputStream);
Element root = doc.getDocumentElement();
parseBeanDefinitions(root);
}
/**
* 遍历root结点
*/
private void parseBeanDefinitions(Element root) throws Exception {
NodeList nodes = root.getChildNodes();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
parseBeanDefinition(ele);
}
}
}
/**
* 遍历bean
*/
private void parseBeanDefinition(Element ele) throws Exception {
String name = ele.getAttribute("id");
String className = ele.getAttribute("class");
BeanDefinition beanDefinition = new BeanDefinition();
beanDefinition.setBeanClassName(className);
processProperty(ele, beanDefinition);
registry.put(name, beanDefinition);
}
/**
* 遍历属性
*/
private void processProperty(Element ele, BeanDefinition beanDefinition) {
NodeList propertyNodes = ele.getElementsByTagName("property");
for (int i = 0; i < propertyNodes.getLength(); i++) {
Node propertyNode = propertyNodes.item(i);
if (propertyNode instanceof Element) {
Element propertyElement = (Element) propertyNode;
String name = propertyElement.getAttribute("name");
String value = propertyElement.getAttribute("value");
if (value != null && value.length() > 0) {
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, value));
} else {
String ref = propertyElement.getAttribute("ref");
if (ref == null || ref.length() == 0) {
throw new IllegalArgumentException("ref config error");
}
BeanReference beanReference = new BeanReference(ref);
beanDefinition.getPropertyValues().addPropertyValue(new PropertyValue(name, beanReference));
}
}
}
}
/**
* 获取Map
*/
public Map<String, BeanDefinition> getRegistry() {
return registry;
}
}
XmlBeanFactory:
public class XmlBeanFactory implements BeanFactory {
/**
* 把<id,BeanDefinition>的键值对注册到这个里头
*/
private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
private List<String> beanDefinitionNames = new ArrayList<>();
private List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
/**
* 关联过来
*/
private XmlBeanDefinitionReader beanDefinitionReader;
public XmlBeanFactory(String location) throws Exception {
beanDefinitionReader = new XmlBeanDefinitionReader();
loadBeanDefinitions(location);
}
/**
* 获取bean
*/
public Object getBean(String name) throws Exception {
BeanDefinition beanDefinition = beanDefinitionMap.get(name);
if (beanDefinition == null) {
throw new IllegalArgumentException("no this bean with name " + name);
}
Object bean = beanDefinition.getBean();
if (bean == null) {
bean = createBean(beanDefinition);
bean = initializeBean(bean, name);
beanDefinition.setBean(bean);
}
return bean;
}
/**
* 创建Bean,通过反射
*/
private Object createBean(BeanDefinition bd) throws Exception {
Object bean = bd.getBeanClass().newInstance();
applyPropertyValues(bean, bd);
return bean;
}
/**
* 注入属性
*/
private void applyPropertyValues(Object bean, BeanDefinition bd) throws Exception {
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(this);
}
for (PropertyValue propertyValue : bd.getPropertyValues().getPropertyValues()) {
Object value = propertyValue.getValue();
if (value instanceof BeanReference) {
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getName());
}
try {
Method declaredMethod = bean.getClass().getDeclaredMethod(
"set" + propertyValue.getName().substring(0, 1).toUpperCase()
+ propertyValue.getName().substring(1), value.getClass());
declaredMethod.setAccessible(true);
declaredMethod.invoke(bean, value);
} catch (NoSuchMethodException e) {
Field declaredField = bean.getClass().getDeclaredField(propertyValue.getName());
declaredField.setAccessible(true);
declaredField.set(bean, value);
}
}
}
/**
* 初始化
*/
private Object initializeBean(Object bean, String name) throws Exception {
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
bean = beanPostProcessor.postProcessBeforeInitialization(bean, name);
}
for (BeanPostProcessor beanPostProcessor : beanPostProcessors) {
bean = beanPostProcessor.postProcessAfterInitialization(bean, name);
}
return bean;
}
/**
* 载入BeanDefinition和BeanPostProcessor
*/
private void loadBeanDefinitions(String location) throws Exception {
beanDefinitionReader.loadBeanDefinitions(location);
registerBeanDefinition();
registerBeanPostProcessor();
}
/**
* 加入到Map中
*/
private void registerBeanDefinition() {
for (Map.Entry<String, BeanDefinition> entry : beanDefinitionReader.getRegistry().entrySet()) {
String name = entry.getKey();
BeanDefinition beanDefinition = entry.getValue();
beanDefinitionMap.put(name, beanDefinition);
beanDefinitionNames.add(name);
}
}
/**
*
*/
public void registerBeanPostProcessor() throws Exception {
List beans = getBeansForType(BeanPostProcessor.class);
for (Object bean : beans) {
addBeanPostProcessor((BeanPostProcessor) bean);
}
}
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
beanPostProcessors.add(beanPostProcessor);
}
/**
* 根据类型获取Bean
*/
public List getBeansForType(Class type) throws Exception {
List beans = new ArrayList<>();
for (String beanDefinitionName : beanDefinitionNames) {
if (type.isAssignableFrom(beanDefinitionMap.get(beanDefinitionName).getBeanClass())) {
beans.add(getBean(beanDefinitionName));
}
}
return beans;
}
}
AOP实现
AOP 是基于动态代理模式实现的,具体实现上可以基于 JDK 动态代理或者 Cglib 动态代理。其中 JDK 动态代理只能代理实现了接口的对象,而 Cglib 动态代理则无此限制。
简化实现流程:
- AOP 逻辑介入 BeanFactory 实例化 bean 的过程
- 根据 Pointcut 定义的匹配规则,判断当前正在实例化的 bean 是否符合规则
- 如果符合,代理生成器将切面逻辑 Advice 织入 bean 相关方法中,并为目标 bean 生成代理对象
- 将生成的 bean 的代理对象返回给 BeanFactory 容器,到此,AOP 逻辑执行结束
2.2 基于 JDK 动态代理的 AOP 实现
代理对象生成器的逻辑主要写在了 JdkDynamicAopProxy 类中,这个类的有两个方法,其中 getProxy 方法用于生成代理对象。invoke 方法是 InvocationHandler 接口的具体实现,包含了将通知(Advice)织入相关方法中
public abstract class AbstractAopProxy implements AopProxy {
protected AdvisedSupport advised;
public AbstractAopProxy(AdvisedSupport advised) {
this.advised = advised;
}
}
/**
* 基于 JDK 动态代理的代理对象生成器
* Created by code4wt on 17/8/16.
*/
final public class JdkDynamicAopProxy extends AbstractAopProxy implements InvocationHandler {
public JdkDynamicAopProxy(AdvisedSupport advised) {
super(advised);
}
/**
* 为目标 bean 生成代理对象
* @return bean 的代理对象
*/
@Override
public Object getProxy() {
return Proxy.newProxyInstance(getClass().getClassLoader(), advised.getTargetSource().getInterfaces(), this);
}
/**
* InvocationHandler 接口中的 invoke 方法具体实现,封装了具体的代理逻辑
* @param proxy
* @param method
* @param args
* @return 代理方法或原方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodMatcher methodMatcher = advised.getMethodMatcher();
// 1. 使用方法匹配器 methodMatcher 测试 bean 中原始方法 method 是否符合匹配规则
if (methodMatcher != null && methodMatcher.matchers(method, advised.getTargetSource().getTargetClass())) {
// 获取 Advice。MethodInterceptor 的父接口继承了 Advice
MethodInterceptor methodInterceptor = advised.getMethodInterceptor();
/*
* 2. 将 bean 的原始方法 method 封装在 MethodInvocation 接口实现类对象中,
* 并把生成的对象作为参数传给 Adivce 实现类对象,执行通知逻辑
*/
return methodInterceptor.invoke(
new ReflectiveMethodInvocation(advised.getTargetSource().getTarget(), method, args));
} else {
// 2. 当前 method 不符合匹配规则,直接调用 bean 的原始方法 method
return method.invoke(advised.getTargetSource().getTarget(), args);
}
}
}
ProxyFactory 实现代码:
/**
* AopProxy 实现类的工厂类
*/
public class ProxyFactory extends AdvisedSupport implements AopProxy {
@Override
public Object getProxy() {
return createAopProxy().getProxy();
}
private AopProxy createAopProxy() {
return new JdkDynamicAopProxy(this);
}
}
测试类:
public class XmlBeanFactoryTest {
@Test
public void getBean() throws Exception {
System.out.println("--------- AOP test ----------");
String location = getClass().getClassLoader().getResource("spring.xml").getFile();
XmlBeanFactory bf = new XmlBeanFactory(location);
HelloService helloService = (HelloService) bf.getBean("helloService");
helloService.sayHelloWorld();
}
}
测试结果:
上一篇: Spring IOC基础(一)
下一篇: Spring(二)IOC