Java中的代理模式

16 篇文章 0 订阅
10 篇文章 0 订阅

1. 静态代理

接口

public interface ICeo {

    void meeting(String name) throws InterruptedException;
}

目标类

public class Ceo implements ICeo{

    public void meeting(String name) throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("和"+name+"谈成了34亿的项目");
    }
}

代理类

public class CeoProxy implements ICeo{

    private Ceo ceo;

    public CeoProxy(Ceo ceo) {
        this.ceo = ceo;
    }

    @Override
    public void meeting(String name) throws InterruptedException {

        System.out.println("秘书登记来访: "+name);
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        ceo.meeting(name);
        stopWatch.stop();
        double totalTimeMillis = stopWatch.getTotalTimeSeconds();
        System.out.println("耗时: "+totalTimeMillis);

    }
}

测试

public class CeoTest {

    public static void main(String[] args) throws InterruptedException {
        Ceo ceo = new Ceo();
        CeoProxy ceoProxy = new CeoProxy(ceo);
        ceoProxy.meeting("XXX");

    }
}

2. JDK动态代理

接口

public interface IDao {

    void select();
}

目标类

public class UserDao implements IDao{
    @Override
    public void select() {
        try {
            Thread.sleep(2000);
            System.out.println("select ----");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

动态代理类
在这里插入图片描述

public class JdkProxy implements InvocationHandler {

    private Object target;

    public JdkProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        StopWatch stopWatch = new StopWatch();
        System.out.println("前置方法");
        stopWatch.start();
        Object obj = method.invoke(target, args);
        stopWatch.stop();
        System.out.println("后置方法");
        System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());
        return obj;
    }
}

测试

public class DaoTest {

    public static void main(String[] args) {
        UserDao userDao = new UserDao();
        IDao dao = (IDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), UserDao.class.getInterfaces(), new JdkProxy(new UserDao()));
        dao.select();
    }
}

总结:

  1. 动态生成代理类
  2. 通过实现接口生成代理类(目标接口必须实现接口)
  3. 代理类是实现接口的方式
  4. 调用目标类使用反射调用
  5. 目标类调用本类方法只会代理一次

3. CGLib动态代理

在这里插入图片描述

目标类

public class ZlmDao {

    public void select(){
        try {
            Thread.sleep(2000);
            System.out.println("select ---");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

代理类

public class CglibProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        System.out.println("前置增强");
        Object result = proxy.invokeSuper(obj, args);
        stopWatch.stop();
        System.out.println("后置增强");
        System.out.println("耗时: "+stopWatch.getTotalTimeSeconds());
        return result;
    }
}

测试

public class ZlmDaoTest {
    public static void main(String[] args) {
        //实例化增强器
        Enhancer enhancer = new Enhancer();
        //设置需要代理的目标类
        enhancer.setSuperclass(ZlmDao.class);
        //设置拦截对象回调的实现类
        enhancer.setCallback(new CglibProxy());
        //生成代理类
        ZlmDao zlmDao = (ZlmDao) enhancer.create();
        zlmDao.select();
    }
}

总结

  1. 通过ASM第三方框架动态代理
  2. 无需接口(final修饰的类和方法除外)
  3. 代理类通过继承目标类的方式实现代理
  4. 调用目标类,使用子类调用父类的方式直接调用
  5. invokeSuper目标类中调用本类方法会再次代理
  6. incoke目标类中调用本来方法只会调用一次
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值