代理实现的几种方式

代理实现的几种方式

代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.

静态代理

在使用静态代理时,需要定义一个接口或父类,被代理对象和代理对象一起实现或继承相同的接口或父类。在程序启动之前,代理类的.class文件已经存在。代理类可以是程序员直接创建的.java文件,也可以是通过某些工具生成的.java文件。

//接口
interface Project{
    void println(String s);
}
//实现类
class ProjectC implements Project{
    @Override
    public void println(String s){
        System.out.println("this is  message :"+s);
    }
}
//静态代理
class ProjectP1 implements Project{
    private ProjectC projectC;

    public ProjectP1(ProjectC projectC){
        this.projectC = projectC;
    }
    @Override
    public void println(String s) {
        System.out.println("this is proxy message");
        System.out.println("---------------------");
        projectC.println(s);
    }
    
}
//测试
public class test11_30 {
    public static void main(String[] args) {
        //无代理
        ProjectC projectC = new ProjectC();
        projectC.println("ok ok");
        System.out.println("");
        //静态代理
        ProjectP1 projectP1 = new ProjectP1(new ProjectC());
        projectP1.println("ok ok");
    }
}

动态代理

jdk代理

jdk可以使用java.lang.reflect.Proxy来生成代理对象。然后通过实现InvocationHandler接口在 invoke 方法中调用具体的方法。
Proxy.newProxyInstance 方法来实例化动态生成的代理类,而这个方法中的参数分别代表的含义是:
ClassLoader loader: 被代理类的类加载器
Class<?>[] interfaces: 被代理类实现的接口
InvocationHandler h: 实现指定接口InvocationHandler的实现类

//jdk代理
class ProjectInvocation implements InvocationHandler{

    Object target;
    public ProjectInvocation(Object target){
        super();
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("动态代理:jdk");
        Object invoke = method.invoke(target);;
        System.out.println("代理结束");
        return invoke;
    }
    
}
//工厂方法
class ProjectP2{
    private InvocationHandler  iHandler;
    private Object target;
    public ProjectP2(Object target ){
        this.target = target;
        this.iHandler = new ProjectInvocation(target);
    }

    public Object getProxy(){
        Object newProxyInstance = Proxy.newProxyInstance(
                    target.getClass().getClassLoader(),
                    target.getClass().getInterfaces(),
                    iHandler);
        return newProxyInstance;
    }
}

cglib代理

创建Enhancer对象,并设置被代理类的类对象(即Class对象)为其父类。
实现MethodInterceptor接口,编写自定义的拦截器,用于处理方法调用。
将自定义的拦截器对象设置为Enhancer对象的回调对象。
调用Enhancer对象的create()方法创建代理对象。
客户端调用代理对象的方法时,代理对象会调用拦截器的intercept()方法,并将被代理方法的相关信息传递给该方法。
在intercept()方法中,可以编写自定义的逻辑来处理方法调用,比如记录日志、检查权限等。

//cglib动态代理
class DynamicProxy implements MethodInterceptor  {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("动态代理:cglib");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("代理结束");
        return result;
    }
}
public class test11_30 {
    public static void main(String[] args) {
        //无代理
        ProjectC projectC = new ProjectC();
        projectC.println("ok ok");
        System.out.println("");
        //cglib
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(ProjectC.class);
        //代理类
        enhancer.setCallback(new DynamicProxy());

        ProjectC proxySubject = (ProjectC) enhancer.create();

        proxySubject.println("ok ok");
    }
}
posted @ 2023-11-30 20:10  kte66  阅读(43)  评论(0)    收藏  举报