设计模式-代理模式

普通代理模式

  1. 定义一个接口 Subject
  2. 该接口的实现类 RealSubject
  3. 代理实现类的类 ProxySubject 实现接口同时内部含有一个实现类的实例
public interface Subject{

    void execute();
}

public class RealSubject implements Subject{

    @Override
    public void execute(){
        System.out.println("execute real subject");
    }
}

public class ProxySubject implements Subject{
    private RealSubject realSubject;
    
    public ProxySubject(RealSubject realSubject){
        this.realSubject = realSubject;
    }
    
    @Override
    public void execute(){
        System.out.println("before");
        realSuject.execute();
        System.out.println("after");
    }
}

public class Client{

    public static void main(String[] args){
        Subject subject = new ProxySubject(new RealSubject());
        subject.execute();
    }
}

动态代理

分为两种实现

  • JDK代理
  • Cglib代理

JDK代理

  1. 定义接口Subject;
  2. 使用 java.lang.reflect.Proxy 类;
  3. 代理类实现 InvocationHandler 接口;

注意:只能基于接口进行动态代理。

public interface Subject{

    void execute();
}

public class RealSubject implements Subject{
    
    @Override
    public void execute(){
        System.out.println("execute real subject");
    }
}

public class ProxySubject implements InvocationHandler{

    private RealSubject realSubject;
    
    public ProxySubject(RealSubject realSubject){
        this.realSubject = realSubject;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

       System.out.println("before jdk");
       Object result = null;
       try {
          result = method.invoke(realSubject, args);
       } catch (Exception e) {
          System.out.println("ex:");
          throw e;
       } finally {
          System.out.println("after jdk");
       }
       return result;
    }
}

public class Client{

    public static void main(String[] args){
        
        //生成代理类的实现类
        Subject subject = (Subject)Proxy.newProxyInstance(Client.class.getClassLoader(),new Class[]{Subject.class},new ProxySubject(new RealSubject));
        subject.execute();
    }
}

Cglib代理

通过继承的方法实现。

maven中引入cglib依赖

<dependency>
	<groupId>cglib</groupId>
	<artifactId>cglib</artifactId>
	<version>3.2.10</version>
</dependency>

继承 MethodInterceptor 接口。

public class CglibProxy implements MethodInterceptor {

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

        System.out.println("before cglib");
        Object result = null;
        try {
            result = methodProxy.invokeSuper(o, objects);
        } catch (Exception e) {
            System.out.println("ex:" + e.getMessage());
            throw e;
        } finally {
            System.out.println("after cglib");
        }
        return result;
    }
}

public class Client {

    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new CglibProxy());
        Subject subject = (Subject) enhancer.create();
        subject.execute();
    }
}

jdk和cglib代理比较

  1. JDK只能通过针对有接口的类的接口方法进行动态代理。
  2. Cglib基于继承实现动态代理,无法对static、final类进行代理。
  3. Cglib基于继承实现动态代理,无法对private、static方法进行代理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值