Spring 复习

一、Spring是如何创建一个bean对象的

1、推断构造方法

先推断构造方法,判断要用哪个构造方法(当一个类有多个构造方法,程序员没有指定要用哪个的时候,就会找无参的用,没有就会报错)我们可以在要用的构造方法上加@Autowired注解

如果是有参构造,这个参数spring哪里拿的呢?去那个单例map池拿的,如果有直接用,没有就创建一个bean,这个情况就可能出现循环依赖的问题,后面说。

他是怎么找的呢,先根据参数的类名来找,如果找到一个这个类型的bean那就是,如果多个再根据名字去找

2、实例化阶段和依赖注入 

利用类的构造方法得到这个对象

然后依赖注入(给前面那些对象的属性赋值,先遍历对象的所有字段,判断属性上有没有autowired注解,就利用反射给这个对象的属性赋值)

单例bean是怎么做到的?

底层是用map来做到的,我们的key就是bean的名字,他getbean的时候就会去map里面找key,存在就把value返回

所有先去找,如果没有就把对象创建出来然后放到map单例池

依赖注入之后:

3、初始化阶段

有个初始化前和初始化和初始化后

初始化前:方法加上注解就会在这个步骤执行执行@PostConstant

初始化:找有没有实现initalizingbean这个接口,实现就了初始化,强制转化为InitializingBean然后调用afterPropertiesSet()这个方法

初始化后(AOP):aop之后会产生代理对象,会把代理对象放到map单例池还是之前的普通对象呢?应该是放代理对象,我们用的对象都是从这个单例池拿的,所有代理对象放。

bean的实例化和初始化有什么区别

实例化是通过构造方法得到bean的对象,初始化就是执行某个方法(实例化出来对象的某个方法,可以自己定义)

4、AOP

aop之后会产生代理对象,代理对象的属性是空,是怎么复制呢?

底层是用cglab进行动态代理赋值的,先执行自己的aop切面逻辑,我们创建一个target属性,把普通类的对象赋值给target属性,用代理对象的时候先执行自己的,然后用target对象来调用原本的方法。就能完成赋值而且可以aop

二、spring事务底层是怎么工作的

我们aop期间,切面做完我们要会检查有没有加@Transactional注解的,加了就有事务,会创建事务管理器,然后新建数据库连接conn,为什么不给jdbctemplete来建立呢?因为如果是他建立,每次执行sql建立一次,就不是一个事务里面了。

他会把自动提交关闭,让他执行完一个sql不自动提交,全部执行完没有抛出异常,就commit,异常就rollback

为什么有时候spring事务会失效?

必须是代理对象在调用方法的时候注解才会生效

@Configuration注解类上事务才有用,为什么?

没加的情况

如果没加Configuration注解那么jdbctemplete 和transactionManager的datasource是两个对象

jdbctemplate会先去spring事务管理器拿连接再去执行sql,他怎么拿呢?去threadLocal里面拿,我们的spring事务管理建立好连接之后会放到threadlocal里面。

threallocal里面有个map<datasource,conn>里面拿

jdbc会拿自己datesouse作为key去mao里面拿,如果没拿到就自己建立连接。他自己建立的连接每次执行完就会提交,所以事务失效了

加了

加了这个注解后,我们这个类就会变成代理类,代理对象取new jdbcTemplate的时候的DataSource会去spring里面找,如果没有就让spring的事务管理器创建然后返回,保证他们的DataSource是同一个对象

猜你喜欢

转载自blog.csdn.net/weixin_54232666/article/details/129304824