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

MyBatis - 代理

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

MyBatis - 代理

在不改变原有代码情况下,实现对原有代码的增强

案例

张三找律师打官司

静态代理

特点:代理类代码是写死的

优点:在不改变原有代码的情况下实现了对原有业务增强

缺点:一个目标类就需要一个代理类,不便于业务拓展

  1. 定义接口,规定核心业务(代理对象与目标对象做的是一样的事情)

    //规定代理对象与目标对象之间所做的核心业务
    public interface Speak {
        void say();
    }
  2. 编写目标类(实现核心的业务)

    public class 张三类 implements Speak{
        @Override
        public void say() {
            System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
        }
    }
  3. 编写代理类(代理目标类--实现对目标的增强)

    public class 律师类 implements Speak {
        // 创建目标类
        private 张三类 张三;    
        public 律师类(张三类 张三) {
            this.张三 = 张三;
        }
        @Override
        public void say() {
            System.out.println("巴拉巴拉...接下来由原告述说");
            张三.say();// 真正做核心业务还是目标对象,代理对象只是在目的对象的基础上增强
        }
    }
  4. 测试

    public static void main(String[] args) {
        张三类 张三 = new 张三类();
        律师类 律师 = new 律师类(张三);
        // 真正的是代理类方法
        律师.say();
    }

动态代理

特点:代理类代码是动态生成

JDK动态代理

特点

  1. 基于接口实现(invocationhandler)

  2. 根据不同目标对象,生成不同代理对象

实现

  1. 定义接口,规定核心业务

    public interface Speak {
        void say();
    }
  2. 编写目标类

    public class 张三类 implements Speak{
        @Override
        public void say() {
            System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
        }
    }
  3. 编写JDK动态代理

    public class JDKProxy implements InvocationHandler {
        // 目标对象
        private Object 客户;
        public JDKProxy(Object obj) {
            this.客户 = obj;
        }
        // 增强代码写在invoke方法
        // proxy:代理对象
        // method:待增强的方法(接口中定义的方法)
        // args:待增强方法的参数
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("巴拉巴拉...接下来由原告述说");
            // 用完目标对象方法时可能有返回
            Object result = method.invoke(客户, args);
            return result;
        }
    }
  4. 生成代理对象

    public static void main(String[] args) {
        张三类 张三 = new 张三类();
        // 调用Proxy类的newProxyInstance静态方法生成代理对象
        Speak speak = (Speak) Proxy.newProxyInstance(张三.getClass().getClassLoader(), 张三.getClass().getInterfaces(), new JDKProxy(张三));
        speak.say();
    }

CGLIB动态代理

特点

基于类的继承实现(MethodInterceptor)

需要导包(cglib、asm)

实现

  1. 编写目标对象

    public class 张三类{
        public void say() {
            System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
        }
    }
  2. 编写代理类(实现MethodInterceptor)

    public class MyProxy implements MethodInterceptor {
        // 目标对象
        private Object target;
        public MyProxy(Object obj) {
            this.target = obj;
        }
        // intercept:编写增强的代码
        // method:待增强的方法
        // arg:待增强的方法需要的参数
        @Override
        public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
            System.out.println("巴拉巴拉...接下来由原告述说");
            Object result = method.invoke(target, arg2);//目标对象方法的返回值 如果为void 则为null
            return result;
        }
    }
  3. 获取代理对象

    public static void main(String[] args) {
        张三类 张三 = new 张三类();
        MyProxy myProxy = new MyProxy(张三);
        // 第一个参数:目标对象类型
        // 第二个参数:实现MethodInterceptor类的对象
        张三类 create = (张三类) Enhancer.create(张三.getClass(), myProxy);
        create.say();
    }

注意

代理类中默认将接口所有方法进行增强,若想对指定方法增强可自定义注解打标记,代理类中去判断标记

创建注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface NeedAdd {}

方法中添加注解

public interface Speak {
    @NeedAdd
    void say();
    int cry(int time);
}

根据方法是否存在注解进行使用

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object result = null;
    // 判断是否存在注解标记
    if(method.isAnnotationPresent(NeedAdd.class)) { 
        System.out.println("巴拉巴拉...接下来由原告述说");
        // 用完目标对象方法时可能有返回
        result = method.invoke(客户, args);
    }else {
        // 用完目标对象方法时可能有返回
        result = method.invoke(target, args);
    }   
    return result;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/996119.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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