栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【无标题】

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【无标题】

动态代理 1、JDK动态代理:必须有接口

分类:

有实现类,代理可以增强功能,典型场景,Service方法加上事务

没有实现类,代理可以实现功能,典型场景,MyBatis的Mapper接口

例子1:有实现类

编写接口

public interface TargetInterface {
    void test1();
    int test2(String s);
}

编写实现类

public class TargetClass implements TargetInterface {
    @Override
    public void test1() {
        System.out.println("TargetClass test1");
    }

    @Override
    public int test2(String s) {
        System.out.println("TargetClass test2,参数:" + s);
        return 10;
    }
}

实现InvocationHandler接口的类

public class WnInvocationHandler implements InvocationHandler {
    private TargetInterface targetInterface;

    public WnInvocationHandler(TargetInterface targetInterface) {
        this.targetInterface = targetInterface;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("start transaction");   //执行代理类方法前增强的功能
        Object r = method.invoke(targetInterface, args);  //执行代理类方法
        System.out.println("commit transaction");  执行代理类方法后增强的功能
        return r;
    }
}

产生代理对象

 public static void main(String[] args) {
        TargetClass targetClass = new TargetClass();
        targetClass.test1();
        //产生代理对象
        TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(TestJdkProxy.class.getClassLoader(), new Class[]{TargetInterface.class},new WnInvocationHandler(targetClass));
        proxy.test1();    //实现功能增强,一定访问的是代理对象

        int r=proxy.test2("aaa");
        System.out.println(r);
    }
}

例子2:无实现类

编写接口

public interface TargetInterface {
    void test1();

    int test2(String s);
}

产生代理

public static void main(String[] args) {
    TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(TestJdkProxy.class.getClassLoader(), new Class[]{TargetInterface.class}, new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("自己的逻辑");
            return 1;
        }
    });
    proxy.test1();

    int r=proxy.test2("aaa");
    System.out.println(r);

}
2、cglib动态代理,无需接口

实现被代理类,不用实现任何接口

public class CglibTarget {
    public void test1() {
        System.out.println("CglibTarget test1");
    }

    public int test2(String s) {
        System.out.println("CglibTarget test2,s=" + s);
        return 10;
    }
}

使用cglib产生代理对象

引入依赖

        
            cglib
            cglib-nodep
            3.3.0
        

Java代码:

 public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(CglibTarget.class);  //设置代理类的父类
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("前置增强");
                Object r = methodProxy.invokeSuper(o, objects);  //调用目标类的方法
                System.out.println("后置增强");
                return r;
            }
        });

        CglibTarget proxy = (CglibTarget) enhancer.create();
        System.out.println(proxy instanceof CglibTarget);
        proxy.test1();
        System.out.println(proxy.test2("aaa"));
    }

3、区分

jdk动态代理产生的代理对象实现了被代理的接口,继承了Proxy类

cglib动态代理产生的代理对象继承了被代理的目标类,重写方法实现功能增强

注意点:

cglib使用的继承并重写方法实现增强功能,被代理类的方法如果是private,final,static其中一个修饰,cglib失效

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1028205.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号