Spring之代理模式

Posted 居诸小筑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring之代理模式相关的知识,希望对你有一定的参考价值。

AOP基础之代理设计模式

1. 静态代理模式

静态设计模式解决了软件分层过程中额外的功能代码侵入模块的问题,将额外的功能代码提取到了代理中进行,但是静态代理实现的代理者中存在大量重复代码,并没有解决代码重复问题。在真正开发中,包括spring底层,基本不会使用静态代码。

2. 动态代理-java内置

在java中提供了动态代理实现的工具类,直接使用该工具类就可以创建出代理者,并且可以通过内置的回调函数指定代理在工作时的执行逻辑,从而实现基于jdk原生api的动态代理机制。

/**
*classLoader:用来生成代理者类的类加载器,通常可以传入被代理者类的类加载器。
*interfaces:要求生成的代理者实现的接口们,通常就是实现和代理者相同的接口,保证具有和代理者相同的
*    方法
*invocationHandler:用来设定回调函数的回调接口,使用者需要写一个类实现此接口,从而实现其中的invoke方法
*在其中编写代码处理代理者调用方法时的回调过程,通常在这里调用真正对象上的方法,并且在方法之前或之后做额外的操作。


static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

/**
*proxy:代理者
*method: 当前调用的方法对象
*args:当前调用的方法的参数数组
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)

  • 优点:不需要像静态代理一样,将被代理方法都实现一遍,只需要在回调函数中进行处理。
  • 缺点:java的动态代理是通过代理者实现与被代理者相同的接口来保证两者具有相同的方法,如果被代理者想要被代理的方法不属于任何接口,则生成的代理者自然无法具有该方法,也就无法实现对该方法的代理。
    也即,java的动态代理机制是基于接口进行的,受制于要代理的方法是否有接口的支持。

3. 动态代理-第三方包cglib实现

CGLIB是第三方提供的动态代理实现工具,不管有没有接口都可以实现动态代理。
其原理是:生成的动态代理是被代理者的子类,所以代理者具有和父类即被代理者相同的方法,从而实现代理。
这种方式基于继承,不再受制于接口。

public UserService getProxy(){
        //1.创建增强器
        Enhancer enhancer = new Enhancer();
        //2.指定要实现的接口们
        enhancer.setInterfaces(userService.getClass().getInterfaces());
        //3.指定父类
        enhancer.setSuperclass(userService.getClass());
        //4.设置回调函数
        enhancer.setCallback(
                new MethodInterceptor() {
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                        try{
                            System.out.println("记录日这");
                            System.out.println("控制权限");
                            System.out.println("开启事务");
                            Object retobj = method.invoke(userService, objects);
                            System.out.println("提交事务");
                            return retobj;
                        }catch (Exception e){
                            System.out.println("回滚事务");
                            e.printStackTrace();
                            throw new RuntimeException(e);
                        }

                    }
                });

        //5.生产代理者
        UserService proxy = (UserService) enhancer.create();
        return proxy;
    }

对比可知,cglib实现动态代理,需要一步一步自己手动设置,而java内置的动态代理是封装好了的。

  • 优点:无论是否有接口都可以实现动态代理,使用场景基本不受限。
  • 缺点:第三方提供的动态代理机制,不是原生的,需要导入第三方开发包才可以使用。

以上是关于Spring之代理模式的主要内容,如果未能解决你的问题,请参考以下文章

Spring之AOP(核心思想:代理模式)

代理设计模式之静态代理与动态代理(超..)详解

Spring系列设计模式之代理模式

设计模式之代理模式

Spring AOP基础之JDK动态代理

Spring之代理模式实例