代理模式(java动态代理)

代理模式

为其他对象提供一个代理,以控制这个对象的访问,在客户端与目标对象之间起到中介作用,属于结构型模式

作用

保护和增强目标对象

静态代理

显示代理目标对象,通过硬编码完成代理工作,不适用于目标类型较多的场景

动态代理

对目标类实现统一增强,与静态代理一样,都是生成目标类的增强类来完成功能,不过静态代理使用硬编码方式,动态代理通过反射等技术动态的生成代理对象,代理逻辑与业务逻辑是互相独立的,没有耦合,代理1个类或100个类要做的事情没有任何区别

java JDK的动态代理(Proxy类)

下面以房产中介与房屋拥有者为例

  1. 必须实现同一个的目标接口
// 房屋拥有者
public interface HomeOwner {
    public void lookHome();
    public void sendHome();
}
  1. 实现两个房屋拥有者
public class LiSi implements HomeOwner{
    @Override
    public void lookHome() {
        System.out.println("星期天可以看");
    }

    @Override
    public void sendHome() {
        System.out.println("50w可以卖");
    }
}
public class ZhangSan implements HomeOwner{
    @Override
    public void lookHome() {
        System.out.println("20好可以来看房");
    }

    @Override
    public void sendHome() {
        System.out.println("100万可以卖房");
    }
}

  1. 实现房产中介(核心)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class HomeProxy implements InvocationHandler {
    HomeOwner pHomeOwner;
    public HomeOwner getInstance(HomeOwner homeOwner){
        this.pHomeOwner = homeOwner;
        Class clazz = pHomeOwner.getClass();
        return (HomeOwner)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
    }

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

    public void before(){
        System.out.println("商量时间");
    }

    public void after(){
        System.out.println("收佣金");
    }
}
  1. 测试类
// 中介可以完美代理不同的人
public class Test {
    public static void main(String[] args) {
        HomeOwner homeProxy = new HomeProxy().getInstance(new ZhangSan());
        homeProxy.lookHome();
        homeProxy.sendHome();


        HomeOwner homeProxy1 = new HomeProxy().getInstance(new LiSi());
        homeProxy1.lookHome();
        homeProxy1.sendHome();
    }
}

基于Cglib实现动态代理(因为JDK代理必须要实现共同接口)

  1. 引入依赖
 
            cglib
            cglib
            3.3.0
 
  1. 实现代理对象(基于继承,生成子类)
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CglibHomeProxy 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 res = methodProxy.invokeSuper(o, objects);
        after();
        return res;
    }

    public void before(){
        System.out.println("商量时间");
    }

    public void after(){
        System.out.println("收佣金");
    }
}

  1. 测试
public class Test {
    public static void main(String[] args) {
        LiSi liSiProxy = (LiSi) new CglibHomeProxy().getInstance(LiSi.class);
        liSiProxy.lookHome();
    }
}

你可能感兴趣的:(代理模式(java动态代理))