一文看懂代理模式

发布于:2021-09-28 05:49:14

什么是代理模式

代理模式主要对我们方法执行之前与之后实现增强


代理模式应用场景
    日志的采集权限控制实现aopMybatis mapperSpring的事务全局捕获异常Rpc远程调用接口代理数据源

代理模式实现的原理

代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色,Proxied)以及代理类角色(Proxy),如上图所示:



?


?


抽象主题角色:可以是接口,也可以是抽象类;


委托类角色:真实主题角色,业务逻辑的具体执行者;


代理类角色:内部含有对真实对象RealSubject的引用,负责对真实主题角色的调用,并在真实主题角色处理前后做预处理和后处理。


代理模式创建方式
静态代理

静态代理需要自己人工编写代理类代码


基于接口实现方式


public class OrderServiceProxy ?implements ?OrderService{
????private OrderService orderService;
????public OrderServiceProxy(OrderService orderService) {
????????this.orderService = orderService;
????public String addOrder(String userName, String userPwd) {
????????return result;

?

?

public interface OrderService {
????/**

?

?

public class Test001 {
????public static void main(String[] args) {

?


?


基于继承的实现方式


public class OrderServiceProxy ?extends OrderServiceImpl {
????private OrderService orderService;
????public OrderServiceProxy(OrderService orderService) {
????????this.orderService = orderService;
????public String addOrder(String userName, String userPwd) {
????????return result;

?


?


动态代理与静态代理的区别

?


动态代理不需要写代理类对象,通过程序自动生成,而静态代理需要我们自己写代理类对象。


?


动态代理

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。


动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成 。


?


Jdk动态代理


JDK动态代理的一般步骤如下:


1.创建被代理的接口和类;


2.实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;


3.调用Proxy的静态方法,创建代理类并生成相应的代理对象;


实现原理:利用拦*骰票匦胧迪諭nvocationHandler接口中的invoke方法实现对


我们的目标方法增强。


public class JdkInvocationHandler implements InvocationHandler {
????/**
????public JdkInvocationHandler(Object target) {
????????this.target = target;
????/**
????????return result;
????public T getProxy() {
????????return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
????????????????target.getClass().getInterfaces(), this);

?


JdkInvocationHandler jdkInvocationHandler = new JdkInvocationHandler(new OrderServiceImpl());

?


加上该代码:


?


    获取代理的生成的class文件

System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true")


?



?


?

CGLIB动态代理


利用asm字节码技术,生成子类实现对目标方法实现增强


实现方式


Maven依赖


<dependencies>
????<dependency>
????????<groupId>cglibgroupId>
????????<artifactId>cglibartifactId>
????????<version>3.2.12version>
????dependency>


?


?


核心代码


public class CglibMethodInterceptor implements MethodInterceptor {
????public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
????????return reuslt;

?


?


System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\code");

?


?


?


?


Jdk与Cglib动态代理的区别


    Jdk动态代理利用反射技术生成匿名的代理类走InvokeHandler回调方法实现增强,同时也是一种基于接口的方式实现代理。Cglib动态代理利用asm字节码技术生成一个子类覆盖其中的方法实现增强,同时采用fastClass机制对整个代理类建立索引比反射效率要高在Spring中如果需要被代理的对象如果实现了接口采用Jdk动态代理,没有实现接口则使用Cglib动态代理。

?

相关推荐

最新更新

猜你喜欢