Java 动态代理

动态代理

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产生代理对象

引入依赖

        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib-nodep</artifactId>
            <version>3.3.0</version>
        </dependency>

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失效

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值