spring的理解与其注解的分析

1.  首先理解一下事务是如何被代理的。

  我们只需要在springboot启动类上加一个注解,然后在方法上加上,那么该方法在出现异常的时候就会进行回滚,那么此时有几个需要我们来解答以下。

 

 

 

问题1: 为什么我们在获取的时候会获取到一个代理对象?

问题2: 代理对象什么时候生成的?

问题3: 代理对象存放在哪里?

 

接下来会一一进行回答。

  首先查看方法调用 context.getBean("")。  可以发现他调用了doGetBean方法,然后调用了 getSingleton方法,最终定位在了 singletonObjects 这个map中,

  其是一个单例缓存池,key:beanName  value:单例对象

此时会引出一个常见的面试题:spring 是如何解决循环依赖的问题。

  这个先不讲,等以后在讲。

 

那我们进行get的时候,那么就一定会有一个方法对这个map进行一个put操作。

  此时通过方法的查找,发现有一个有一个方法:  增加单例模式

  

 

 

   这个方法只是往上走的话,找到getSingleton方法,  再往上找的话会找到doGetBean方法。

  dogetBean会有两次获取getSingleton的方法,刚启动的时候调用的话,此时肯定返回的肯定是null。

  那么第二次调用的时候,代码如下: 这个方法是从单例缓存池中获取对象,如果没获取对象,就会调用singletonFactory.getObject();

  此时就相当于调用createBean()方法,  因其是一个函数式接口,可以使用lamda表达式,所以当前版本不是一个工厂,而是一个lamda表达式。

  

 

 

   createBean中有一行代码:  resolveBeforeInstantiation()  通过bean的后置处理器来及墨西哥后置处理生成代理对象。但是这里不会生成代理对象,

  因为真实的对象并没有生成。

  往下走的话,会遇到这一句话 doCreateBean() 方法,该步骤是我们真正创建bean实例对象的过程。

 

  那么doCreateBean中有两行代码比较重要

  1. 通过推断构造函数,使用合适的实例化策略来创建新的实例。

  

 

 

   2.  populateBean是先给对象进行赋值,然后在给对象进行初始化操作(这里生成了代理对象)

  

 

 

 

  我们再进入initializeBean这个方法。

  这个方法有三个流程:

  1. 在初始化之前调用bean的后置处理器的postProcessorsBeforeInitialization 方法

  

 

 

   2. 调用初始化方法

  

 

 

   3. 调用bean的后置处理器的PostProcessorsAfterInitialization方法

  

 

 

   在后置处理器的after方法返回了代理对象。

  那么就可以知道,代理对象是在BeanPostProcessors.after方法生成的代理对象。

  此时线索断了,不知道是哪个后置处理器搞的事,那么就要从开启代理对象的注解开始进行分析,这个注解是 @EnableTransactionManagement。

  这个注解详细信息:

  

 

 

   @Import注解可以为我们容器中导入组件 ----> TransactionManagementConfigurationSelector 。

  我们点进去这个类:  

  其中selectImports会被回调,方法的返回值是我们需要导入类的全类名路径,然后这个类就会被加载到容器中。

  

 

 

   一般默认是PROXY这个选项:

  此时导入两个类:AutoProxyRegistrar 和ProxyTransactionManagementConfiguration

  点进去AutoProxyRegistrar这个类:其实现了这个接口 ImportBeanDefinitionRegistrar这个接口

  这个类也会被回调,会导入InfrastructureAdvisorAutoProxyCreator 创建器

  这个类实现了BeanPostProcessor这个方法, 此时又可以玩下去了,因为找到了一个和事务相关的后置处理器。这个方法在其父类中:

  

 

 

   在该后置方法中,我们的事务和aop对象就是在这里生成的。

  那么开始分析wrapIfNecessary这个方法,找到了这个方法:

  

 

  那么其中的advisor从哪来的呢?

  我们找到另外一个类:ProxyTransactionManagementConfiguration :

  

 

   其有一个adivsor,叫BeanFactoryTransactionAttributeSourceAdvisor和TranactionAttributeSource

  

   这两个组件就是用来解析它的,通过匹配,发现如果有advisor被匹配上了,就会返回该advisor。

  当找到一个的时候此时就会找到真正创建代理对象的地方。

   

 

   进去这个方法,会调用到这个下面这个方法:

  

 

   因此可以在注解上加上proxyTargetClass = true 强制走CGlib代理。

  此时代理对象创建完成。

  但其实还有一个类也被注入其中: 该类为 TransactionInterceptor类,其继承自MethodInterceptor。所以需要从其invoke开始

  

 

   具体的事务处理工作交给了这个Interceptor进行完成。

  主要看其invoke方法。

  

  接下来讲一讲spring的IOC和AOP的理解。

  IOC意思是 Inversion of control (控制反转),其实现方法是通过DI(dependency injection)依赖注入实现的。将对象交给Spring容器去管理,谁需要某个类的时候进行注入就可以了。

  其主要为了降低类之间的耦合度,并且不用每次在new出一个对象出来。

  

  AOP面向切面编程

  其主要是将程序中的交叉业务逻辑,封装成一个切面,然后注入到目标对象中。 通过代理的方式来实现,这样可以提高程序的内聚性。

 

posted @ 2022-08-21 18:29  小罗咯  阅读(38)  评论(0编辑  收藏  举报