Spring——创建代理对象最后一步创建的(ProxyFac

Spring——创建代理对象最后一步创建的(ProxyFactory)分析

这一篇文章旨在分析Spring中创建代理对象的环节中,最后一步创建代理代理对象的具体的操作。以及涉及到的相关的东西

在开始之前,必须要清楚Spring关于代理的几个概念:切面,通知,连接点,切入点,织入,目标类。建议直接看官网-AOP Concepts

都知道,Spring创建代理对象有两种方式, JDK-Proxy和Cglib-Proxy方式。在之前的文章中, 已经说了,如果是Jdk就要关注InvocationHandler。如果是Cglib就要关注MethodCallBack和MethodFilter。主要大方向没有错,具体的细节慢慢的就清楚了。下面的代码,会从ProxyFactory开始分析。

ProxyFactory

创建代理对象的工厂类.先看类图

ProxyFactory.png

类图是有点长了,这里列出类里面的方法能更好的了解一个类所做的事情。

从类图上来看,ProxyFactory是有配置的语义的。并且实现了Advised(实现类持有创建代理对象的配置,这个配置包含Interceptors,advice,Advisors,proxied interfaces)。

还要注意DefaultAopProxyFactory。他是一个AOP代理的创建工厂,最终是通过他来创建代理对象的。他是在ProxyCreatorSupport创建的(ProxyCreatorSupport里面有对应的set方法,他肯定持有引用关系)。并且DefaultAopProxyFactory依赖于AdvisedSupport。

类图就到这里了,还是从构造方法和一些常用的方法开始

方法分析

image-20211208224903799.png

主要就几种类型,设置targetClass(目标类),代理的接口。还有Interceptor(表示在运行的时候拦截事件,实现类,主要两种,方法拦截,和构造方法拦截,下面会说)。

public ProxyFactory(Object target) {
   setTarget(target);
   setInterfaces(ClassUtils.getAllInterfaces(target));
}
复制代码

比如这个方法,在设置targetClass的时候会拿到目标类上面所有实现的接口的集合。包括他的父类,他是循环做的。一直会找上去。

再看看ProxyFactory#getProxy方法,这里的方法的重载比较多,我就挑一个分析分析

public Object getProxy() {
		return createAopProxy().getProxy();
	}
复制代码

这个方法就很简单了,因为他继承了ProxyCreatorSupport,ProxyCreatorSupport又关联了DefaultAopProxyFactory。所以,这里的createAopProxy()方法代其实调用的是DefaultAopProxyFactory的createAopProxy方法。在调用createAopProxy的时候,需要传递一个AdvisedSupport的引用。这里传递的是this。也就是ProxyFactory。这样,他们就持有了创建代理期间所需要的所有的配置了。

AopProxyFactory分析

AopProxyFactory.png

通过DefaultAopProxyFactory创建不同的代理方式。这种模式就是工厂模式

此外,还需要知道,他们都和AdvisedSupport有依赖或者组合的关系。要知道AdvisedSupport持有创建代理对象期间所有的配置信息。

如何判断是JdkDynamicAopProxy还是ObjenesisCglibAopProxy?

image-20211209211450960.png

主要是上面红框里面的代码,这些代码都有什么意思?

  1. config.isOptimize()

    这个意思没有搞懂

  2. config.isProxyTargetClass()

    true:表示要直接代理目标类,而不是用指定的接口。也就是说,会直接代理TargetSource里面暴露出来的目标类。但是如果targetClass是一个接口,就会创建使用jdk的proxy,如果是一个类,就会使用Cglib。

  3. hasNoUserSuppliedProxyInterfaces()

    是否没有用户自己提供的接口,这个判断是通过传递进来的AdvisedSupport,判断他里面的interfaces是否为空,如果只有一个,判断是否是SpringProxy。SpringProxy是一个标记接口,只要是Spring创建的对象,都有这个。

  4. targetClass.isInterface()

    是否是接口

  5. Proxy.isProxyClass(targetClass)

    是否是一个代理对象,这个判断是通过Proxy(java Proxy)来做的。

到这里,对应的创建代理的工厂类就确定好了,因为JAVA Proxy和Cglib Proxy的过程比较多,下一篇文章写,这里就先不写了,这篇文章作为他们的先导片。为了之后进行的分析,下面主要是围绕着一些概念性的东西来做说明

区别

Advice和Advisor和Advised有啥区别?

  1. Advice

    这个接口只有一个功能:(动作)

    首先他是个Advice的标签接口,Advice表示动作,在合适的地点采用合适的动作,这就是动作的意思。

    此外,在实际用的时候也是将Advice作为一个入口操作,在里面可以组成一条Intercept的链来调用。

    看看他的子类:

image-20211209215954314.png

红框里面的这些Advice是常见的,在之后会看到他们的身影。

通知的话,在Spring里面,通知是有好几个种类的,这里就不在详细的说了,

这里要说说Advice的几个子接口。

  • AfterAdvice(后置),关于后置就多了,比如单纯的方法后面执行(后置通知),在方法执行之后异常的时候通知(异常通知)。等等

  • BeforeAdvice(前置)

  • Interceptor(拦截器)

    ​ 先说功能,表示在可以通过这个拦截器,拦截到一些事件(比如方法调用,构造方法调用)。

    ​ 这个接口里面是空的, 这是一个标记接口,但是他的子类就有作用了,在日后的代理对象的操作中有很多使用的场景。

  1. Advisor

    这个接口有两个功能:动作和判断。

    动作意思是他持有Advice。

    判断表示这个动作在啥时候用,具体体现就是这个类是否满足,比如,比如这个类是否是一个继承与什么样的类,或者实现了什么特定的接口,或者,条件是否满足(比如说,在什么类的什么方法上面,来做这个事情。)最典型的就是(JointPoint)。

image-20211209220224041.png

  1. Advised

    这个接口只有一个功能:配置。

    配置的意思是它持有创建代理对象所需要的配置。

    这个类图在上面已经分析了。

introduction具体有什么含义?

功能:可以在创建代理对象之前,再引入一些新的接口。但是要记住,只要代理对象创建好了,就不能在添加了,因为这个时候代理的类已经在内存里面了。不能在更改了。

具体看看IntroductionInfo和IntroductionInterceptor接口的含义和接口的实现类的功能。
因为连在一起有点长,这里分为好几个,具体看后面的博客。

到此,结束了。
关于博客这件事,我是把它当做我的笔记,里面有很多的内容反映了我思考的过程,因为思维有限,不免有些内容有出入,如果有问题,欢迎指出。一同探讨。谢谢。