SSM总结

Spring
Spring框架底层源码-Bean的生命周期:要想让一个类成为Bean,首先得让类成为Bean定义----类上带有或者包含有@Component的注解是可以成为Bean定义的或者Bean标签,这种事Xml的方式,这里我们不讲述因为过时了-----首先跟据包路径扫描,所有的类都会被编译成Class对象,这里有Resource对象存储,该对象是一个数组。--------接着遍历每个Class对象,带有或者包含有@Component注解的类会被添加到Bean定义集合去,添加之前会进行一次过滤,虽然该类上带有注解,但是如果是抽象类或者是接口则不能生成Bean定义--------遍历Bean定义集合,给每个Bean定义设置属性比如Bean定义的作用域,单例还是原型的,这里Bean定义有一个属性 类型是Object,这个属性这里存储的是该类的类名,解析完Bean定义之后会添加到Bean定义Map中去------遍历Bean定义Map,首先合并Bean定义,因为Bean定义可能有父亲,自己没有的属性可以继承父亲的,合并好的Bean定义会添加到合并的那个Map中去,创建Bean的时候会从合并的那个Map中去拿-------遍历合并好的Bean定义,然后跟据Bean定义创建Bean,这里有两种情况一个是FactoryBean,另一个则不是,如果是FactoryBean,Bean的返回类型则是getObject返回的类型,如果不是则直接调用CreatBean方法创建Bean如果Bean是单例的则放入单例池。如果是原型的则不放入,下次用到该Bean时重新创建---------不管是创建FactoryBean还是普通的单例Bean,都会调用creatbean方法,这里算是正式进入Bean的生命周期了。--------首先,获取Bean定义的那个Object类型的属性,跟据类名利用反射创建一个Class对象,替换掉这个Object属性。---------实例化前:如过程序员实现了实例化前这个接口,这里会调用一个方法,该方法可以返回该Bean的类型,如果设置了返回类型则直接跳到初始化那一步--------实例化:这里Spring会根据推断构造方法进行实例化,如果该类中没有构造方法的话,Spring默认会根据无参的构造方法创建对象,如果是有参的构造方法且只有一个的话Spring则会使用该构造方法,如果在Xml中则需要指定该方法,如果有多个构造方法的话其中包含无参的则会使用无参的,如果没有则需要在要使用的构造方法上加删@Autowired注解,在Xml中则需要指定-------这里会调用Bean的后置处理器postProcessMergedBeanDefinition()方法:他的作用是查找注入点,也就是寻找类上代友@Autowired注解的属性,会把这些属性生成一个个对象存入集合中,注入点集合-------实例化后:如果程序员实现了这个接口,可以对实例化好的对象进行处理,Spring中很少用到--------自动注入:Spring自己填充属性,带有类似@Value的属性--------属性填充:对@Autowired的属性进行填充,这里用到上面的注入点,会遍历该集合跟据注入点查找对应的Bean,如果匹配找到则会将其合并存入到一个Map中缓存,下次用到则直接在缓存中拿(这里提到***依赖注入***:这里说明一件事情,如果创建BeanA和BeanB,A中B的属性,B中有A的属性,在创建A时,对其属性B进行填充,此时还在A的生命周期中B并没有创建好,这种情况我们称之为循环依赖。------解决这个问题需要三级缓存,一级缓存存放的时经过完整生命周期的单例Bean,二级缓存存储的是不完整的单例Bean,三级缓存也是。------在创建A时,经过实例化还未进行属性填充之前,将A实列放入三级缓存,然后A进行属性填充发现需要B,这时候没有BSpring就要创建B,进入B的生命周期,同样将B的实例放入三级缓存,接着进行属性填充,发现需要A,这个时候就去三级缓存中拿A实例。接着B创建完生命周期结束,同样A也创建好生命周期结束。----如果这个世界这么简单那就好了继续看!!—>刚才说的A没有进行Aop如果进行Aop了那么三级缓存中拿到的那个对象,和A初始化之后的对象是一个对象吗–答案不是,那怎么办!!!我为你解答。在对应的实例放入三级缓存的时候会有一个对应的Lambda表达式这个时候这个表达式不会执行。当创建B,B需要对属性A进行填充的时候这个时候就会执行这个Lambda表达式,这个表达式的作用就是判断A需不需要进行Aop如果需要则进行,然后将这个Aop对象放入二级缓存,这个时候从二级缓存中拿到这个Aop对象进行属性填充。B生命周期结束,接着A继续进行生命周期,在初始化这一步的时候不会进行Aop了,因为已经进行Aop过了,他也会进行判断是否进行过Aop,接着A生命周期结束创建完毕。!!!)---------执行Aware:执行一些Aware接口-------初始化前:如果程序员执实现了初始化前接口,则可以对依赖注入的Bean进行处理-------初始化:查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法,执行BeanDefinition中指定的初始化方法--------初始化后:对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。

Spring整合Mybatis
Spring会把所有的mapper扫描到并生成Bean定义,然后把这些Bean定义进行修改把BeanClass修改为MapperFactoryBean,把AutowireMode修改为byType。-------扫描完成后,Spring就会基于BeanDefinition去创建Bean了,相当于每个Mapper对应一个FactoryBean------在MapperFactoryBean中的getObject方法中,调用了getSqlSession()去得到一个sqlSession对象,然后根据对应的Mapper接口生成一个Mapper接口代理对象,这个代理对象就成为Spring容器中的Bean,sqlSession对象是Mybatis中的,一个sqlSession对象需要SqlSessionFactory来产生,所以Spring容器中要存在SqlSessionFactory类型的bean或者SqlSessionTemplate类型的bean。

Spring AOP
OOP表示面向对象编程,是一种编程思想,AOP表示面向切面编程,也是一种编程思想,而我们上面所描述的就是Spring为了让程序员更加方便的做到面向切面编程所提供的技术支持,换句话说,就是Spring提供了一套机制,可以让我们更加容易的来进行AOP,所以这套机制我们也可以称之为Spring AOP。
AOP中的概念

  1. Aspect:表示切面,比如被@Aspect注解的类就是切面,可以在切面中去定义Pointcut、Advice等等
  2. Join point:表示连接点,表示一个程序在执行过程中的一个点,比如一个方法的执行,比如一个异常的处理,在Spring AOP中,一个连接点通常表示一个方法的执行。
  3. Advice:表示通知,表示在一个特定连接点上所采取的动作。Advice分为不同的类型,后面详细讨论,在很多AOP框架中,包括Spring,会用Interceptor拦截器来实现Advice,并且在连接点周围维护一个Interceptor链
  4. Pointcut:表示切点,用来匹配一个或多个连接点,Advice与切点表达式是关联在一起的,Advice将会执行在和切点表达式所匹配的连接点上
  5. Introduction:可以使用@DeclareParents来给所匹配的类添加一个接口,并指定一个默认实现
  6. Target object:目标对象,被代理对象
  7. AOP proxy:表示代理工厂,用来创建代理对象的,在Spring Framework中,要么是JDK动态代理,要么是CGLIB代理
  8. Weaving:表示织入,表示创建代理对象的动作,这个动作可以发生在编译时期(比如Aspejctj),或者运行时,比如Spring AOP

代理对象执行过程
9. 在使用ProxyFactory创建代理对象之前,需要往ProxyFactory先添加Advisor
2. 代理对象在执行某个方法时,会把ProxyFactory中的Advisor拿出来和当前正在执行的方法进行匹配筛选
3. 把和方法所匹配的Advisor适配成MethodInterceptor
4. 把和当前方法匹配的MethodInterceptor链,以及被代理对象、代理对象、代理类、当前Method对象、方法参数封装为MethodInvocation对象
5. 调用MethodInvocation的proceed()方法,开始执行各个MethodInterceptor以及被代理对象的对应方法
6. 按顺序调用每个MethodInterceptor的invoke()方法,并且会把MethodInvocation对象传入invoke()方法
7. 直到执行完最后一个MethodInterceptor了,就会调用invokeJoinpoint()方法,从而执行被代理对象的当前方法

Spring事务基本执行原理
个Bean在执行Bean的创建生命周期时,会经过InfrastructureAdvisorAutoProxyCreator的初始化后的方法,会判断当前当前Bean对象是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,匹配逻辑为判断该Bean的类上是否存在@Transactional注解,或者类中的某个方法上是否存在@Transactional注解,如果存在则表示该Bean需要进行动态代理产生一个代理对象作为Bean对象。该代理对象在执行某个方法时,会再次判断当前执行的方法是否和BeanFactoryTransactionAttributeSourceAdvisor匹配,如果匹配则执行该Advisor中的TransactionInterceptor的invoke()方法,执行基本流程为:

  1. 利用所配置的PlatformTransactionManager事务管理器新建一个数据库连接
  2. 修改数据库连接的autocommit为false
  3. 执行MethodInvocation.proceed()方法,简单理解就是执行业务方法,其中就会执行sql
  4. 如果没有抛异常,则提交
  5. 如果抛了异常,则回滚

Spring事务传播机制:
在开发过程中,经常会出现一个方法调用另外一个方法,那么这里就涉及到了多种场景,比如a()调用b():1. a()和b()方法中的所有sql需要在同一个事务中吗?2. a()和b()方法需要单独的事务吗?3. a()需要在事务中执行,b()还需要在事务中执行吗?4. 等等情况…所以,这就要求Spring事务能支持上面各种场景,这就是Spring事务传播机制的由来。那Spring事务传播机制是如何实现的呢? 先来看上述几种场景中的一种情况,a()在一个事务中执行,调用b()方法时需要新开一个事务执行: 1. 首先,代理对象执行a()方法前,先利用事务管理器新建一个数据库连接a2. 将数据库连接a的autocommit改为false3. 把数据库连接a设置到ThreadLocal中4. 执行a()方法中的sql5. 执行a()方法过程中,调用了b()方法(注意用代理对象调用b()方法)i. 代理对象执行b()方法前,判断出来了当前线程中已经存在一个数据库连接a了,表示当前线程其实已经拥有一个Spring事务了,则进行挂起ii. 挂起就是把ThreadLocal中的数据库连接a从ThreadLocal中移除,并放入一个挂起资源对象中iii. 挂起完成后,再次利用事务管理器新建一个数据库连接biv. 将数据库连接b的autocommit改为falsev. 把数据库连接b设置到ThreadLocal中vi. 执行b()方法中的sqlvii. b()方法正常执行完,则从ThreadLocal中拿到数据库连接b进行提交viii. 提交之后会恢复所挂起的数据库连接a,这里的恢复,其实只是把在挂起资源对象中所保存的数据库连接a再次设置到ThreadLocal中6. a()方法正常执行完,则从ThreadLocal中拿到数据库连接a进行提交这个过程中最为核心的是:在执行某个方法时,判断当前是否已经存在一个事务,就是判断当前线程的ThreadLocal中是否存在一个数据库连接对象,如果存在则表示已经存在一个事务了。

Spring MVC
在这里插入图片描述在这里插入图片描述在这里插入图片描述Mybatis
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值