java设计模式 第一章: 代理模式

从今天开始更新java设计模式相关的东西,之前虽然也对java设计模式有过学习单都是走马观花或者应付面试.现在工作中遇到了挑战,编写出优雅的代码成为非常迫切的事情;

代理模式

代理模式是java中常用的设计模式,在比如说在spring中的事物管理就是使用的代理模式;

1.为什么要使用代理模式

所有的设计模式都具有一个目标: 提高代码的复用率,这一点非常重要;

代理模式可以抽取通用的代码生成代理类,通过代理类执行目标对象的方法实现了代码的复用,经典的案列:spring的AOP;

2.代理模式的分类

  1. 静态代理
  2. 动态代理
    • java动态代理
    • cglib动态代理
2.1静态代理

静态代理非常简单,代理类持有目标类的对象,在执行目标方法的时候可以进行一些自定义的操作

public class UserDaoProxy implements IUserDao{

    private IUserDao target;

    public UserDaoProxy(IUserDao target){
        this.target = target;
    }

    @Override
    public CansResult save() {
        // 记录日志
        System.out.println("记录日志--------------");

        CansResult res = target.save();

        System.out.println("打印返回值:" + res);
        return res;
    }
}
2.2 动态代理

静态代理属于硬编码在工作中应用场景不多一般只用来学习方便理解,动态代理才是我们工作中常接触到的,动态代理可以在程序执行过程中动态生成代理类,在执行目标方法之前之后执行我们想要的操作,比如记录日志,权限校验等等;

java动态代理

java动态代理有一个缺点: 需要实现接口,如果没有实现接口则不能使用java的动态代理但是可以使用cglib动态代理

public class ProxyFactory {
    /**
     * 目标对象
     */
    private Object target;

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

    /**
     * 给目标对象生成代理
     * @return
     */
    public Object getProxyInstance(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (Object proxy, Method method, Object[] args) -> {
                    System.out.println("开始事务2");
                    //执行目标对象方法
                    Object returnValue = method.invoke(target, args);
                    System.out.println("提交事务2");
                    return returnValue;
                });
    }
}
    /**
     * 使用java动态代理
     * 需要接口
     */
    @Test
    public void javaDynamicProxy() {
        IUserDao proxy = (IUserDao) new ProxyFactory(userDao).getProxyInstance();
        proxy.save();
    }
cglib动态代理

cglib动态代理应用广泛,因为没有java动态代理必须实现接口的限制,并且据说效率也更高

public class CglibProxyFactory implements MethodInterceptor {

    /**
     * 维护目标对象
     */
    private Object target;

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

    /**
     * 给目标创建一个代理对象
     *
     * @return
     */
    public Object getProxyInstance() {
        //1.工具类
        Enhancer en = new Enhancer();
        //2.设置父类
        en.setSuperclass(target.getClass());
        //3.设置回调函数
        en.setCallback(this);
        //4.创建子类(代理对象)
        return en.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

        System.out.println("开始事务");
        // 执行目标对象方法
        Object invoke = method.invoke(target, objects);
        System.out.println("提交事物");
        return invoke;
    }
}
    /**
     * Cglib 代理
     * 并没有实现接口
     */
    @Test
    public void cglibDynamicProxy() {
        // 代理对象
        UserDaoImpl proxyInstance = (UserDaoImpl) new CglibProxyFactory(userDao).getProxyInstance();
        // 执行方法
        proxyInstance.save();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值