代理模式

动态代理动态的生成代理对象,对满足条件的目标对象皆可以生成代理代理对象,
没有静态代理一个目标类一个代理类的问题
解耦合
 

JDK动态代理

需要目标类有实现接口

代理类与目标类实现相同接口

接口

package testJdkProxy;
//jdk动态代理必须使用接口
public interface JDKProxy {
public void sayHelloWorld();
}

 

实现类

package testJdkProxy;
//接口实现,真实主题实现类
public class ImplementClass implements JDKProxy {

    @Override
    public void sayHelloWorld() {
        // TODO Auto-generated method stub
        System.out.println("hello world");
    }

}

设置代理

package testJdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//代理,代理操作类
public class DynamicProxy implements InvocationHandler{
//真实对象     (通过实现类实现)
private Object target=null;
//建立代理对象和真实对象之间的关系
/**
 * 
 * @param target 真实对象
 * @return  代理对象 
 */
 //接受真实主题实现类(目标对象),把代理对象下挂在接口下 生成下挂后的代理对象来实例化接口
public Object bind(Object target) {
    //保存真实对象,invoke里面会用到    实例化的真实主题实现类 对象——>指向被代理的真实主题
    this.target=target;
    return Proxy.newProxyInstance(
            //实现类的类加载器      实现类所实现的接口          代理对象     ——>把代理对象下挂在接口下
            target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//代理逻辑
/**
 * @param proxy 代理对象
 * @param method 当前调度方法
 * @param args 当前方法参数
 * @return 代理结果返回
 * @throws Throwable 异常
 */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    // TODO Auto-generated method stub
    System.out.println("进入代理逻辑方法");
    System.out.println("在调度真实对象之前的服务--------");
    //------------------------------------------------------------------执行前业务逻辑
    Object object=method.invoke(target, args); //相当于调用sayhelloworld方法
    //---------------------------------------------------------------------执行后业务逻辑
    System.out.println("在调度真实对象之后的服务");
    //invoke的返回值
    return object;
}

}

 

测试

package testJdkProxy;

public class ToTest {
public static void main(String[] args) {
    new ToTest().testJdkProxy();
}
public void testJdkProxy() {
    //创建代理
        DynamicProxy jdk=new DynamicProxy();
    //绑定关系,实例化接口,下挂代理JDKProxy接口下,通过代理实例化接口对象 
    JDKProxy  pro=(JDKProxy)jdk.bind(new ImplementClass());
    //此时JDKProxy对象已经是一个代理对象,调用方法的时候,他会自动进入代理的逻辑方法invoke里 重复的业务逻辑不用额外手动调用
    pro.sayHelloWorld();
}
}
通过bind方法绑定代理关系,实例化接口对象,调用方法时自动转入 代理逻辑invoke方法

 

 

CGLIB动态代理

只需要一个非抽象类实现MethodInterceptor
 
使用:
过程:被代理的类——创建代理——使用
依赖:第三方包 要用到 cglib-nodep-2.2.jar 包
实现 代理要implements MethodInterceptor
原理 Cglib代理可以对任何类生成代理,代理的原理是对目标对象进行继承代理,
注意 如果目标对象,被final修饰了,那么该类似无法被cglib代理的
 
 

目标类

package testCGLIBOproxy;

public class ProxyedClass {
    public void sayHello() {
        System.out.println("hellloworld");
    }
}

 

代理类

package testCGLIBOproxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

//CGLIB不需要提供接口,只需要一个非抽象类就能实现动态代理
public class CglibProxyExample implements MethodInterceptor {
    /**
     * 生成代理对象
     * @param cla——Class类
     * @return Class类的CGLIB代理对象
     */
    
    
    public Object getProxy(Class cla) {
        //CGLIB enhancer 增强类对象      加强者
        Enhancer enhancer=new Enhancer();
        //设置代理谁  setSuperclass设置超类  要继承的目标对象
        enhancer.setSuperclass(cla);
        //setCallback设置代理类    定义代理逻辑对象为当前对象,要求当前对象实现MethodInterceptor方法
        enhancer.setCallback(this);
        //生成并返回代理对象
        return enhancer.create();
    }
    /**
     * 代理逻辑方法
     * @param arg0代理对象
     * @param arg1方法
     * @param arg2方法参数
     * @param arg3方法代理
     * @return 代理逻辑返回
     * 
     */
    @Override
    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("调用真实对象前");
        //反射调用真实对象方法 传参数给它
        Object result=arg3.invokeSuper(arg0,arg2);
        //调用真实对象后
        System.out.println("调用真实对象后");
        return result;
    }
    
    
}

 

测试类

package testCGLIBOproxy;

public class TestClass {
public static void main(String[] args) {
    new TestClass().testCGLIB();
}
public void testCGLIB() {
    //创建代理对象
    CglibProxyExample cep=new CglibProxyExample();
    //通过代理实例化被代理对象类
    ProxyedClass obj=(ProxyedClass)cep.getProxy(ProxyedClass.class);
    //与代理关联后,调用方法时,自动进入代理逻辑intercept方法
    obj.sayHello();
}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2023-03-17 11:44  or追梦者  阅读(10)  评论(0编辑  收藏  举报