动态代理的实现方式

一、什么是动态代理?

动态代理是一种编程模式,它允许在运行时创建代理对象,以实现对目标对象的方法进行增强,代理对象同名方法内可以执行原有逻辑的同时嵌入执行其他增强逻辑或者其他对象方法。

二、动态代理的作用

需要将一些非主的公共逻辑无侵入性的应用到某个业务代码逻辑上,例如:日志记录、事务管理、性能监控等,既降低代码的耦合度,也减少代码的重复性。

三、动态代理的使用场景

1、Spring AOP

2、自己手动创建代理对象

四、动态代理的实现技术
1、JDK动态代理技术(基于接口):

(1)使用条件:要求被代理类有接口,代理对象是基于接口动态生成的实现类。

(2)使用方式:

A、在Spring AOP中,目标类有接口的情况下,默认采用该代理技术。

B、在自己需要手动创建代理对象的时候:

// 声明一个接口
public interface JDKService {
    void show(String s);
}

// 进行接口实现
public class JDKServiceImpl implements JDKService{
    @Override
    public void show(String s) {
        System.out.println("JDKService show......"+s);
    }
}

// 主测试代码
public class JDKProxyDemo {
    public static void main(String[] args) {

        JDKService jdkService = new JDKServiceImpl();

        // 使用 JDK动态代理技术,创建代理对象
        Object proxyInstance = Proxy.newProxyInstance(
                jdkService.getClass().getClassLoader(),
                jdkService.getClass().getInterfaces(),
                (Object proxy, Method method, Object[] arg) -> {
                    // proxy:代理对象,method:执行的目标对象方法,arg:执行的目标对象方法参数列表
                    System.out.println("proxy:" + proxy.getClass());
                    Object result = method.invoke(jdkService, arg);
                    System.out.println("arg:" + arg);
                    return result;
                });
        JDKService proxy= (JDKService) proxyInstance;
        proxy.show("hello");
    }
}


/**
  * 执行结果:
  * 方法调用前执行一些逻辑.......
  * JDKService show......hello
  * 方法调用后执行一些逻辑.......
  */

2、Cglib动态代理技术(基于子类):

(1)使用条件:被代理类无接口且不能使用final修饰,代理对象是基于被代理对象动态生成的子对象。

(2)使用方式:

A、在 Spring AOP中,手动配置 <aop:config proxy-target-class="true">强制使用 Cglib方式。

B、在自己需要手动创建代理对象的时候:

// 被代理对象,也就是目标类
public class Target {
    public void show(String s){
        System.out.println("Target show.........."+s);
    }
}

// 增强逻辑
public class Advice {
    public void before(){
        System.out.println("Advice before ......");
    }
    public void after(){
        System.out.println("Advice after .......");
    }
}

// 主测试类
public class CglibProxyDemo {
    public static void main(String[] args) {
        Target target = new Target();// 目标对象
        Advice advice = new Advice();// 增强对象
        Enhancer enhancer = new Enhancer(); // 用来实现 Cglib动态代理的增强器对象
        enhancer.setSuperclass(target.getClass());// 注意用的都是 spring下的spring-core中的类
        // 设置增强器回调
        enhancer.setCallback((MethodInterceptor)(o, method, objects, methodProxy)->{
            advice.before();
            Object result = method.invoke(target,objects);
            advice.after();
            return result;
        });
        // 创建代理对象
        Target proxy = (Target) enhancer.create();
        proxy.show("hello");
    }
}

 /**
   * 执行结果:
   * Advice before ......
   * Target show..........hello
   * Advice after .......
   */
3、两种代理技术图解 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值