设计模式之架构中的代理增强模式

流程分析

在这里插入图片描述
模拟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 实现调用即可:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值