流程分析
模拟Spring的声明式事务控制,在业务层进行增强,我们可以按照如下步骤实现:
1、创建增强类TransactionManager,在里面编写一个增强方法begin
2、创建一个BeanProxy对象,用于给指定包下的对象创建代理
3、每次ParseXml加载解析之后,调用BeanProxy给指定包下的对象创建代理
业务层代理模式增强
1)指定增强位置
首先在spring.xml配置文件中配置一下增强的位置,before表示前置增强, package 表示指定包下的对象进行前置增强, ref 表示指定增强的类, method 表示增强的类中指定的方法。
<!--增强类-->
<bean id="transactionManager" class="com.wangj.framework.aop.TransactionManager"></bean>
<!--package:给该包下所有类的所有方法产生代理 -->
<before package="com.wangj.service.impl" ref="transactionManager" method="begin" />
我们需要创建一个增强类 TransactionManager :
public class TransactionManager {
/**
* 前置增强
*/
public void begin(){
System.out.println("开启事务!");
}
}
2)增强实现
步骤:
1、解析xml,需要获取增强的包,实现增强的类的方法
2、获取所有解析的实例,并判断每个实例是否是该包下的对象
3、如果是该包下的对象,给它创建代理,执行增强
4、将当前对象替换成代理对象
5、将当前对象下的引用属性替换成代理
代理增强类 BeforeProxyBean ,代码如下:
public class BeforeProxyBean implements InvocationHandler {
//被代理的对象
private Object instance;
// 增强的实例
private Object beforeInstance;
// 增强的方法
private Method beforeMethod;
public BeforeProxyBean(Object instance, Object beforeInstance, Method beforeMethod) {
this.instance = instance;
this.beforeInstance = beforeInstance;
this.beforeMethod = beforeMethod;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//前置增强
beforeMethod.invoke(beforeInstance);
// 目标方法调用
return method.invoke(instance);
}
}
创建代理类 ProxyBeanFactory ,代码如下:
public class ProxyBeanFactory {
/*** * 增强操作 */
public static void proxy(Map<String, Object> beans) {
try {
//获取对应前置增强节点信息
Map<String, String> map = XmlBean.before();
if (map == null) {
return;
}
//获取指定的包
String packageinfo = map.get("package");
//获取增强类实例
Object aopInstance = beans.get(map.get("ref"));
//增强方法
Method method = aopInstance.getClass().getDeclaredMethod(map.get("method"));
//增强操作
beforeHandler(beans, aopInstance, method, packageinfo);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void beforeHandler(Map<String, Object> beans, Object aopInstance, Method method, String packageinfo) throws Exception {
for (Map.Entry<String, Object> entry : beans.entrySet()) {
//当前实例的包
String entryPackage = entry.getValue().getClass().getPackage().getName();
//属于增强包下的类,需要增强
if(entryPackage.equals(packageinfo)){
//创建代理
Object proxyInstance = Proxy.newProxyInstance(entry.getValue().getClass().getClassLoader(),
entry.getValue().getClass().getInterfaces(),
new BeforeProxyBean(entry.getValue(), aopInstance, method));
//将非代理对象替换掉
beans.put(entry.getKey(),proxyInstance);
//将实例对象中对应属性替换成代理对象
XmlBean.replaceProxy(beans,entry.getKey(),proxyInstance);
}
}
}
}
在工厂 XmlBeanFactory 实现调用即可: