代理模式

代理模式的优点:

  • 代理模式能将代理对象和真实被调用的目标对象分离
  • 在一定的程度降低系统的耦合性,扩展性好
  • 可以起到保护目标对象的作用
  • 可以增强目标对象的功能

代理模式的缺点

  • 代理模式造成系统设计类的数量增加
  • 在客户端和目标对象中增加一个代理对象,会导致请求处理速度变慢
  • 增加系统的复杂度

静态代理和动态代理的本质区别

  1. 静态代理只能通过手动完成代理操作,如果被代理类增加的新的方法,代理类需要同步增加,违背的开闭原则
  2. 动态代理采用在运行时动态生成代码的方式,取消了对被代理类的扩展限制,遵循开闭原则
  3. 若动态代理要对目标代理的增加逻辑进行扩展,结合策略模式,只需要新增策略变可以完成,无需修改代理类的代码

CGLib 和 JDK 动态代理对比

  1. JDK动态代理实现了被代理对象的接口,CGLib 代理继承了被代理对象
  2. JDK动态代理和CGLib代理都是在运行期生成字节码文件,JDK动态代理直接写Class字节码,CGLib代理是使用ASM框架写Class字节码,CGLib代码实现更复杂,生成的代码里类比JDK动态代理效率低
  3. JDK动态代理调用代理方法是通过反射机制调用的,CGLib代理是通过FastClass 机制直接调用方法的,CGLib代理的执行效率高

接下里分别使用JDK动态代理 和 CGLib 实现业务场景

JDK 动态代理生成对象的步骤:

  1. 获取被代理对象的引用,并通过反射获取它所有的接口
  2. JDK动态代理类生成一个新的类,同时新的类要实现被代理类实现的所有接口
  3. 动态生成java代码,新加的业务逻辑方法由一定的逻辑代码调用
  4. 编译生成新的java代码.class 文件
  5. 重新加载到JVM中

JDK 动态代理

 

创建一个人类的接口 person

/**
 * @Author Lxq
 * @Date 2020/3/24 17:21
 * @Version 1.0
 */
public interface Person {

    public void findLove();
}
创建一个单身客户类 Customer
/**
 * @Author Lxq
 * @Date 2020/3/24 17:31
 * @Version 1.0
 * 单身客户类
 */
public class Customer implements Person{
    @Override
    public void findLove() {
        System.out.println("身高180cm");
        System.out.println("高富帅");
        System.out.println("有8块腹肌");
    }
}
媒婆的代理类 JDKMeipo 
/**
 * @Author Lxq
 * @Date 2020/3/24 17:24
 * @Version 1.0
 * JDK动态代理
 */
public class JDKMeipo implements InvocationHandler {

    // 被代理的对象,把引用保存下来
    private Object target;

    public Object getInstance(Object target) {
        this.target = target;
        Class<?> clazz = target.getClass();
        return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }


    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object invoke = method.invoke(this.target, args);
        after();
        return invoke;
    }

    private void before(){
        System.out.println("我是媒婆:我要给你找对象,现在确认一下你的要求");
        System.out.println("开始配对");
    }

    private void after(){
        System.out.println("如何合适,留下联系方式");
    }
}

 测试代理:

/**
 * @Author Lxq
 * @Date 2020/3/24 16:17
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {
        Person person = (Person) new JDKMeipo().getInstance(new Customer());
        person.findLove();

    }
}

 

CGLib 代理 

CGLMeipo 代理类


/**
 * @Author Lxq
 * @Date 2020/3/24 17:37
 * @Version 1.0
 */
public class CGLMeipo implements MethodInterceptor {

    public Object getInStance(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        // 要把那个设置生效为即将生成的新的父类
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        // 业务的增强
        before();
        Object obj = methodProxy.invokeSuper(o, objects);
        after();
        return obj;
    }

    private void before(){
        System.out.println("我是媒婆:我要给你找对象,现在确认一下你的要求");
        System.out.println("开始配对");
    }

    private void after(){
        System.out.println("如何合适,留下联系方式");
    }
}

测试代理


/**
 * @Author Lxq
 * @Date 2020/3/24 16:17
 * @Version 1.0
 */
public class Test {
    public static void main(String[] args) {

        Customer customer = (Customer) new CGLMeipo().getInStance(Customer.class);
        customer.findLove();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章