(结构型模式)代理模式

63 阅读2分钟

简介

代理模式就是代理对象具备真实对象的功能,并代替真实对象完成相应操作,并能够在操作执行的前后,对操作进行增强处理。典型例子:AOP

静态代理

已找工作内推为例子,求职者找到猎头,猎头帮忙推送简历。

public interface IPerson {
    void send();
}
//求职者
public class Person implements IPerson {
    @Override
    public void send() {
        System.out.println("发送简历");
    }
}
//猎头代理
public class HeadhuntingProxy implements IPerson{
    
    private IPerson iPerson;
    
    public HeadhuntingProxy(IPerson iPerson){
        this.iPerson = iPerson;
    }
    
    @Override
    public void send() {
        iPerson.send();
        System.out.println("查看简历");
    }
}
//使用
public class Demo {

    public static void main(String[] args) {
        IPerson person = new Person();
        HeadhuntingProxy headhuntingProxy = new HeadhuntingProxy(person);
        //猎头推送
        headhuntingProxy.send();
    }
}

JDK动态代理

jdk动态代理过程中实际上代理的是接口,是因为在创建代理实例的时候,依赖的是java.lang.reflect包中Proxy类的newProxyInstance方法。
接下来用JDK动态代理来增强我们的接口。

public interface ITest {
    
    void test();
}
public class Test implements ITest{
    @Override
    public void test() {
        System.out.println("测试");
    }
}
public class JDKProxy implements InvocationHandler {

    private Object bean;

    public JDKProxy(Object bean){
        this.bean = bean;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("开始");
        Object invoke = method.invoke(bean, args);
        System.out.println("结束");
        return invoke;
    }
}
public class Demo {
    public static void main(String[] args) {
        Test test = new Test();
        JDKProxy jdkProxy = new JDKProxy(test);
        ITest o = (ITest) Proxy.newProxyInstance(jdkProxy.getClass().getClassLoader(), new Class[]{ITest.class}, jdkProxy);
        o.test();
    }
}

Cglib动态代理

JDK动态代理的前提条件是,要有接口存在,那还有许多场景是没有接口的,这个时候就需要cglib动态代理了,CGLIB是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB通过继承方式实现代理。

引入依赖

<dependency>
    <groupId>asm</groupId>
    <artifactId>asm</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency>
    <groupId>asm</groupId>
    <artifactId>asm-commons</artifactId>
    <version>3.3.1</version>
</dependency>
<dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-tree</artifactId>
    <version>9.4</version>
</dependency>
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

使用

//Cglib代理类
public class CglibProxy implements MethodInterceptor {
    private Enhancer enhancer=new Enhancer();
    private Object bean;

    public CglibProxy(Object bean) {
        this.bean = bean;
    }

    public Object getProxy(){
        //设置需要创建子类的类
        enhancer.setSuperclass(bean.getClass());
        enhancer.setCallback(this);
        return enhancer.create();

    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("开始");
        Object invoke = method.invoke(bean, objects);
        System.out.println("结束");
        return invoke;
    }
}