JDK动态代理和CGLIB动态代理

什么是AOP?

AOP实际是设计模式的延续,设计模式孜孜不倦所追求的就是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

Aspect是程序设计一个新的中心,AOP并不取代OOP,两者各有各的角色,将职责各自分配给Object与Aspect,会使得程序中各个组件的角色更为清楚。

代理机制分为静态代理和动态代理

本文着重介绍动态代理,静态代理这里不细说(但需要注意:代理对象的一个接口只服务于一种类的对象,而且如果要代理的方法很多,我们势必要为每个方法进行代理,静态代理在程序规模稍大时就必定无法胜任。)

JDK动态代理

Java在JDK1.3之后加入协助开发动态代理功能的类,我们不必为特定对象与方法写特定的代理,使用动态代理,可以使得一个handler服务于各个对象,一个handler必须实现java.lang.reflect.InvocationHandler。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * JDK的动态里要求,被代理对象必须实现接口
 * @author boyas
 */
public class MyHandler implements InvocationHandler {
    //被代理对象
    private Object targetObject;
    //传入被代理对象,返回一个代理对象
    public Object   createProxy(Object targetObject){
        //把需要被代理的对象传入到本对象中
        this.targetObject=targetObject;
        //通过被代理对象生成它的代理对象,并且同MyHandler绑定在一起
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("打开会话连接");
        Object result=method.invoke(targetObject,args);
        System.out.println("有事务提交事务,关流");
        return result;
    }
}

InvocationHandler的invoke()方法会传入代理对象的方法名称与参数,实际上要执行的方法交由method.invoke(),并在其前后加上记录动作,method.invoke()返回的对象是实际方法执行过后的回传结果。

JDK动态代理必须有接口

public interface UserService {
    void insertUser();
}

JDK的动态里要求,被代理对象必须实现接口

public class UserServiceImpl implements UserService {
    @Override
    public void insertUser() {
        System.out.println("执行添加用户方法");
    }
}

创建代理对象

/**
*传入一个被代理对象,返回一个代理对象	
*调用被代理对象中的任何一个方法时,都会使用代理在其前后加上一些动作
*/
public class MainTest {
    public static void main(String[] args) {
        //创建代理对象
        MyHandler myHandler = new MyHandler();
        UserService userService=(UserService)myHandler.createProxy(new UserServiceImpl());
        userService.insertUser();
    }
}

运行
在这里插入图片描述

CGLib动态代理

当代理对象没有实现接口,我们就可以使用CGLIB生成代理,如果采用eclipse可以导入cglib-nodep-2.1_3.jar,如果是IDEA导入cglib依赖就行。

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * cglib动态代理,被代理对象可以没有实现接口
 * 传入被代理对象,返回代理对象,代理对象是被代理对象的子类
 */

public class CGLIBHandler implements MethodInterceptor {
    //被代理对象
    private Object targetObject;
    //传入一个代理对象,返回一个代理对象
    public Object   createProxy(Object targetObject) {
        this.targetObject = targetObject;
        //设置代理对象
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(this.targetObject.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        System.out.println("打开");
        Object invoke=arg1.invoke(targetObject,arg2);
        System.out.println("关闭");
        return invoke;
    }//CGLIB可以生成目标类的子类,并重写父类非final修饰符的方法。
}

没有实现接口

public class UserServiceImpl {
    public void insertUser() {
        System.out.println("执行添加用户方法");
    }
}

测试

public class MainTest {
    public static void main(String[] args) {

        CGLIBHandler cglibHandler=new CGLIBHandler();
        UserServiceImpl userServiceImpl=(UserServiceImpl)cglibHandler.createProxy(new UserServiceImpl());
        userServiceImpl.insertUser();
    }
}

运行
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

༄༊心灵骇客༣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值