写这篇主要是由于自己一直忘记,动态代理在许多地方都是常用,特别是在接触一框架,都有动态代理的影子。

动代理模式是什么,简单来说代理就是在你要执行的核心内容前后进行一些修饰。

应用到程序中:即将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。

一、静态代理

  有动态代理肯定就有静态,静态与动态最直接区别,静态是死的比较容易理解,动态是灵活性比较高,理解起来还需要结合更多实战经验

  下面用一张图来解释这个流程:静态代理就不在阐述了【相信你自己也会写的出来】

  

 

  简单理解:

     代理类 = 实现原始类相同接口 + 添加辅助功能 + 调用原始类的业务方法。

  流程理解:

     例如:现在房东有一个房间要出租,它就会找到中介进行房屋出租,中介发布房子信息,带租户看房子,租户满意就跟房东交房租,签合同。

        中介代理了房屋生成的代理类流程:发布信息 ==》 租户看房 ==》房东签合同、收房租===》完成

  静态代理的问题

  • 代理类数量过多,不利于项目的管理。

  • 多个代理类的辅助功能代码冗余,修改时,维护性差。

  由于静态代理的种种约束,很多场合不在适用,就需要动态代理来弥补不足之处。

  动态代理的思维方式跟静态代理是一致的,找别人来对你要执行的事情进行封装,修饰。

二、JDK动态代理【基于接口】

  TargetInterface:目标对象接口

  Target:目标对象【需被代理对象】

  Advice:增强方法【对目标对象进行增强处理  相当于中介的发布房子、带租客看房】

  TextJDk:代理类【生成最终代理结果】

  TargetInterface:

public interface TargetInterface {
    void save();
}

 

  Target【实现类】:

public class Target implements TargetInterface {
    @Override
    public void save() {
        System.out.println("save running.....");
    }
}

  Advice【增强方法】:

public class Advice {
    public void before(){
        System.out.println("前置增强...");
    }
    public void afterReturning(){
        System.out.println("后置增强...");
    }
}

 

  TextJDK【代理类】

public class JDKTest {
    public static void main(String[] args) {
        Target target = new Target();//目标对象
        Advice advice = new Advice();//增强方法

        //接收的参数应该是目标对象父类
     //
Proxy.newProxyInstance 代理方法
TargetInterface proxy = (TargetInterface)Proxy.newProxyInstance(
                target.getClass().getClassLoader(), //目标对象加载器
                target.getClass().getInterfaces(),//目标对象相同的接口字节码对象数组
                new InvocationHandler() {  //实现代理流程
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        advice.before(); //前置处理
                        Object invoke = method.invoke(target, args); //使用反射执行目标对象方法
                        advice.afterReturning(); //后置处理
                        return invoke; //返回目标对象结果
                    }
                });

        proxy.save(); //运行结果
    }
}

 

//看注释,就不在阐述了==》之所以用目标对象接口来接收是因为 :目标对象相当于代理类返回值的兄弟类【同等级】,会异常

          ==》所以只能用目标对象的上一级来接收,才能实现代理

运行结果:

    

 

 

 

三、cglib动态代理基于父类

  Target:目标对象【需被代理对象】

  Advice:增强方法【对目标对象进行增强处理  相当于中介的发布房子、带租客看房】

  TextCglib:代理类【生成最终代理结果】

  基于父类的代理肯定没有接口,其他与JDK动态一致,不一致的是实现代理的方式,流程是一致

//目标对象
public class Target { public void save() { System.out.println("save running................"); } }
//增强方法
public class Advice { public static void before(){ System.out.println("前置增强。。。。"); } public static void after(){ System.out.println("后置增强。。。。"); } }
//实现代理
public class TextCglib{ public static void main(String[] args) { Target target = new Target(); //基于cglib返回动态代理对象 //创建增强器 Enhancer enhancer = new Enhancer(); //设置父类(目标),没有父类则就是当前类 enhancer.setSuperclass(Target.class); //设置回调[MethodInterceptor:Callback子接口] enhancer.setCallback(new MethodInterceptor() {//代理方法 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //实现代理流程 Advice.before(); Object invoke = method.invoke(target,args);//使用反射执行目标方法 Advice.after(); return invoke; //返回代理结果 } }); //生成代理对象 Target proxy = (Target) enhancer.create(); proxy.save(); } }

  本人也是刚学,上述是基于自己的理解,若出现不正确地方,欢迎指正!

内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/tree-hole/p/13870555.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!