模式介绍

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

静态代理

代理模式中最简单的一种实现方式。

/**
 * 老师接口
 */
public interface ITeacher {
    public void teach();
}

/**
 * 老师实现类
 */
public class Teacher implements ITeacher {

    @Override
    public void teach(){
        System.out.println("今天我们学习如何打野更有效率!");
    }
}
/**
 * 老师代理
 */
public class TeacherProxy {
    private ITeacher teacher;

    public TeacherProxy(ITeacher teacher){
        this.teacher = teacher;
    }

    public void teach(){
        System.out.println("代理开始了!");
        teacher.teach();
        System.out.println("代理结束了!");
    }
}
/**
 * 客户端
 */
public class Client {
    public static void main(String args[]){
       TeacherProxy proxy = new TeacherProxy(new Teacher());
       proxy.teach();
    }
}
结果:
代理开始了!
今天我们学习如何打野更有效率!
代理结束了!

动态代理

动态代理又称 JDK 代理或接口代理,被代理对象必须实现接口。

1、优点:能够以工厂模式生成对应的代理;目标代码改变代理不需要进行改变。

2、缺点:需要代理的目标类,一定要实现接口才行,一定要实现 java.lang.reflect.InvocationHandler 接口。

/**
 * 老师接口
 */
public interface ITeacher {
    public void teach();
}

/**
 * 老师实现类
 */
public class Teacher implements ITeacher {

    @Override
    public void teach(){
        System.out.println("今天我们学习如何打野更有效率!");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 代理工厂
 */
public class ProxyFactory {
    private Object target;

    public ProxyFactory(Object target){
        this.target = target;
    }

    public Object getProxyInstance(){
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        return Proxy.newProxyInstance(classLoader, interfaces, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("JDK代理开始!");
                Object returnObject = method.invoke(target, args);
                return returnObject;
            }
        });
    }
}
/**
 * 客户端
 */
public class Client {
    public static void main(String args[]){
        ITeacher teacher = new Teacher();
        ITeacher proxyTeacher = (ITeacher)new ProxyFactory(teacher).getProxyInstance();
        proxyTeacher.teach();
    }
}
结果:
JDK代理开始!
今天我们学习如何打野更有效率!

Cglib 代理

针对代理的类, 动态生成一个子类, 然后子类覆盖代理类中的方法, 如果是 final 修饰的方法,则不会被重写。

1、优点:能够以工厂模式生成对应的代理;目标代码改变代理不需要进行改变;需要代理的目标类,不一定要实现接口才行。

2、缺点:一定要实现 net.sf.cglib.proxy.MethodInterceptor 接口。

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.2.5</version>
</dependency
/**
 * 老师类
 */
public class Teacher {
    public void teach(){
        System.out.println("今天我们学习如何打野更有效率!");
    }
}
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
/*
 * 代理工厂
 */
public class ProxyFactory implements MethodInterceptor{
    private Object target;
    
    public ProxyFactory(Object target) {
        this.target = target;
    }
    
    public Object getProxy() {
        Enhancer en = new Enhancer();
        en.setSuperclass(target.getClass());  
        en.setCallback(this);     
        return en.create();
    }

    @Override  
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
                                                                        throws Throwable {
        System.out.println("Cglib代理开始了!");
        Object returnValue = proxy.invokeSuper(obj, args);
        return returnValue;
    }
}
/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        ProxyFactory teacherProxy = new ProxyFactory(new Teacher());
        Teacher teacher = (Teacher)teacherProxy.getProxy();
        teacher.teach();
    }
}
结果:
Cglib代理开始了!
今天我们学习如何打野更有效率!

相关文章:

  • 2021-06-29
  • 2021-09-14
  • 2021-10-20
  • 2021-11-23
  • 2022-02-22
  • 2021-07-04
  • 2021-06-08
  • 2021-07-16
猜你喜欢
  • 2021-06-24
  • 2021-11-09
  • 2021-09-25
  • 2021-12-23
  • 2021-08-17
  • 2021-12-21
  • 2021-08-05
  • 2022-02-21
相关资源
相似解决方案