AOP动态代理织入

在之前一篇中,我们介绍了什么是AOP面向切面编程。下面以Spring AOP 为例来详细讲解。
Spring AOP 采用的是动态代理织入
代理是实现AOP的底层技术。
下面介绍两种代理技术:
1. JDK代理技术
2. CGlib代理技术
JDK代理:
InvocationHandler 是一个接口,增强逻辑代码就是放在这个接口的实现类中。
代理类= 目标类 + 增强逻辑。相当于一个新类。

package com.smart.proxy;

import java.lang.reflect.InvocationHandler; //相当于一个编织器,将切面织入目标类
import java.lang.reflect.Method;

public class PerformaceHandler implements InvocationHandler {
    private Object target;  //目标类
    public PerformaceHandler(Object target){
        this.target = target;
    }
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        PerformanceMonitor.begin(target.getClass().getName()+"."+ method.getName());//逻辑代码
        Object obj = method.invoke(target, args);//反射调用目标对象的方法
        PerformanceMonitor.end();//横切逻辑代码
        return obj;
    }
}

PerformaceHander 为一个编织器对象

@Test
    public void proxy() {
        // 业务类正常编码的测试
        // ForumService forumService = new ForumServiceImpl();
        // forumService.removeForum(10);
        // forumService.removeTopic(1012);
        // 使用JDK动态代理
        ForumService target = new ForumServiceImpl();//目标类
        PerformaceHandler handler = new PerformaceHandler(target);//编织器类,在目标类中织入相应的代码逻辑
        ForumService proxy = (ForumService) Proxy.newProxyInstance(target
                .getClass().getClassLoader(),
                target.getClass().getInterfaces(), handler);//生成代理
        proxy.removeForum(10); // 按照目标类所显现接口来调用方法。(可以理解为接口的代理)
        proxy.removeTopic(1012);

proxy 通过静态方法,par1 为目标类的类加载器,par2为目标类的借口,par3位编织器对象。这样就生成了一个目标类增强后的代理类。proxy.调用代理对象的方法时,就会去执行invoke函数。从而实现代码注入

对于没有通过借口定义业务方法的类,我们就必须使用CGlib来操作。CGlib 采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有的父类方法,并顺势织入横切逻辑。

package com.smart.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor {//相当于一个代理创建器支持所有类
    private Enhancer enhancer = new Enhancer();

    public Object getProxy(Class clazz) { //获得代理类
        enhancer.setSuperclass(clazz); //设置目标类
        enhancer.setCallback(this);
        return enhancer.create();//创建代理类
    }

    public Object intercept(Object obj, Method method, Object[] args,//拦截父类所有方法的调用
        MethodProxy proxy) throws Throwable {
        PerformanceMonitor.begin(obj.getClass().getName()+"."+method.getName());//织入
        Object result=proxy.invokeSuper(obj, args);
        PerformanceMonitor.end();
        return result;
    }
}

下面看测试:

@Test
    public void proxy() {
        //使用CGLib动态代理
        CglibProxy cglibProxy = new CglibProxy(); //获取代理创建器
        ForumService forumService = (ForumService)cglibProxy.getProxy(ForumServiceImpl.class);//获取代理向上转型
        forumService.removeForum(10);//父类方法调用,会被intercept拦截,织入增加。
        forumService.removeTopic(1023);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值