华为云计算 云知识 代理模式

代理模式

代理模式是一种结构性模式

结构性模式是解决类或对象组合在一起的经典结构

结构性模式包括:代理模式,桥接模式,装饰者模式,适配器模式,门面模式,组合模式,享元模式

代理模式的原理:在不改变原始类的情况下,通过引入原始类(代理类)的情况下,对原始类附加新的功能。

代理模式又分为静态代理和动态代理

静态代理:程序员手动创建,在程序运行前,已经存在代理类的字节码文件

动态代理:程序运行过程中通过反射创建。

静态代理通过继承或者实现接口的方式,对函数方法进行增强。

缺点:为每一个服务都需要创建一个代理类,如果服务特别多,不利于管理

动态代理:

如果被代理类有接口,使用jdk的动态代理

如果被代理的类没有实现接口,且类没有被final 修饰使用cglib的动态代理。

jdk 动态代理的实现

/**
 * 被代理类实现的接口
 * */
public interface Subject { /** 被代理类要执行的方法 */ void buyHouse();
}
/**
 * @Description: 被代理类

 * @Date: 2020/5/12 17:59
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class RealSubject implements Subject { /** 目标方法 */ public void buyHouse() { System.out.println("我会买房子"); }
}
/**
 * @Description: 代理类  实现InvocationHandle 接口
 *  重写invoke 方法
 * 为什么要实现InvocationHandle 接口  Proxy.newProxyInstance()的第三个参数是一个InvocationHandler接口
 * @Date: 2020/5/12 17:59
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class DynamicProxyHandler implements InvocationHandler { private Object object; public DynamicProxyHandler(final Object object) { this.object = object; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我会找房源"); Object result = method.invoke(object, args); return result; }
}
/**
 * @Description: JDK 动态代理类的测试

 * @Date: 2020/5/12 18:19
 * @Author: fuguowen
 * @Return 
 * @Throws 
 */
public class MainClass { public static void main(String[] args) { /** 创建被代理类 */ Subject subject = new RealSubject(); /** * ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的 * Class[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型 * InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法 * 找到被代理类的类加载器,被代理类实现的接口,代理类 */ Subject proxySubject = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class[]{Subject.class}, new DynamicProxyHandler(subject)); /** 执行被代理类对应的方法 */ proxySubject.buyHouse(); }

}

cglib的动态代理  

CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Description: cglib 动态代理 代理类
 * @Author: Ling.D.S
 * @Date: Created in 2018/11/14 18:36
 */
public class CglibProxy implements MethodInterceptor { private Object target;//业务类对象,供代理方法中进行真正的业务方法调用 //相当于JDK动态代理中的绑定 public Object getInstance(Object target) { this.target = target;  //给业务对象赋值 Enhancer enhancer = new Enhancer(); //创建加强器,用来创建动态代理类 enhancer.setSuperclass(this.target.getClass());  //为加强器指定要代理的业务类(即:为下面生成的代理类指定父类) //设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦 enhancer.setCallback(this); // 创建动态代理类对象并返回 return enhancer.create(); } // 实现回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("我会找房源"); proxy.invokeSuper(obj, args); //调用业务类(父类中)的方法 return null; }
/** * @Description: cglib 动态代理类的单元测试 * @Date: 2020/5/12 18:22 * @Author: fuguowen * @Return * @Throws */ public static void main(String[] args) { /** 创建被代理类 */ RealSubject realSubject = new RealSubject(); CglibProxy cglibProxy = new CglibProxy(); RealSubject realSubjectProxy = (RealSubject) cglibProxy.getInstance(realSubject); realSubjectProxy.buyHouse(); }

参考:

1. https://blog.csdn.net/kbh528202/article/details/84103931

上一篇:weback4.0版本学习(一)

下一篇:JAVA对象的序列化与反序列化

51CTO

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。