Spring生命周期

Bean的生命周期

UserService.class ---> 无参数构造方法 (推断构造方法) ---> 普通对象 ---> 依赖注入(属性赋值) ---> 判断是否有Aware回调--->初始化前 (@PostConstruct) ---> 初始化 (InitializingBean) ---> 初始化后 (AOP) ---> 代理对象 ---> Bean

1、UserService.class

使用@Bean或者@Component来将此类声明为bean

@Component
public class UserService { //beanName为userService
​
     @Autowired
     OrderService OrderService; //beanName为orderService
}

UserService声明为bean,需要从Spring容器中注入OrderService的bean。

2、无参数构造方法 (推断构造方法)
  • 没写构造方法:调用无参构造方法,实例化bean;

  • 写一个构造方法:就使用这个构造方法(这一个无论有参无参)实例化bean

  • 多个构造方法:就调用 无参构造方法 实例化bean,如果没有无参构造方法就会报错。除非某个构造方法上加了@Autowired,就会用这个 构造方法。

3、普通对象

上面那一步推断调用了构造方法后,就会创建一个普通对象(相当于new的一个)。

4、依赖注入(属性赋值)

找到那个添加了@Autowired的属性,然后给属性赋值。那怎么去找,先通过类型查找,查找到多个bean的话,再通过beanName在 Spring存储注册好的Map<beanName,bean对象>中查找。

5、Aware回调

Spring会判断该对象是否实现了BeanNameAware接口、 BeanClassLoaderAware接口、BeanFactoryAware接口,如果实现了,就表示当前 对象必须实现该接口中所定义的setBeanName()、setBeanClassLoader()、 setBeanFactory()方法,那Spring就会调用这些方法并传入相应的参数(Aware回 调)

6、初始化前 (@PostConstruct)

Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法(初始化前

7、初始化 (InitializingBean)

紧接着,Spring会判断该对象是否实现了InitializingBean接口,如果实现了,就表示当前对象必须实现该接口中的afterPropertiesSet()方法,那Spring就会调用当前对象中的afterPropertiesSet()方法(初始化

8、初始化后 (AOP)
流程:

1、找出所有的切面Bean(@Aspect)

2、遍历这些切面Bean

3、遍历每个切面Bean的方法

4、查找哪些方法适配当前要创建Bean的类(当前创建的Bean为UserService,查找的就是切面UserService的方法的切面类的方法),将这些方法缓存到map里面(Map<UserService.class,method>)。

将缓存方法的map中的访求拿出来,在代理类中执行,下面的target是被代理对象。

9、代理对象

如果使用了AOP就用 代理对象做为Bean

10、Bean

没有使用AOP应用 普通对象做为Bean

Spring事务

当我们在某个方法上加了@Transactional注解后,就表示该方法在调用时会开启Spring事 务,而这个方法所在的类所对应的Bean对象会是该类的代理对象。

Spring事务的代理对象执行某个方法时的步骤:

  1. 判断当前执行的方法是否存在@Transactional注解

  2. 如果存在,则利用事务管理器(TransactionMananger)新建一个数据库连接

  3. 修改数据库连接的autocommit为false

  4. 执行target.test(),执行程序员所写的业务逻辑代码,也就是执行sql

  5. 执行完了之后如果没有出现异常,则提交,否则回滚 Spring事务是否会失效的判断标准:某个加了@Transactional注解的方法被调用时,要判 断到底是不是直接被代理对象调用的,如果是则事务会生效,如果不是则失效

小细节:

为什么会普通对象的bean执行事务方法不生效?

扩展:@Transtaional和AOP一样都是创建代理对象的,所以用了@Transtaional,最后创建的Bean也会是代理对象,所以一个bean不是代理对象,调用@Transcational的方法,事务不会生效。

因为@Transactional,所以会创建一个代理对象,上面有事务的代理对象执行方法的步骤,其中代理对象的方法中 事务管理器创建一个连接应该是为了autocommit设置为false的,只有@Transactional实例出的代理对象bean才可以利用事务理器创建一个数据库连接,然后将autocommit设置为false,不设置成false就自动提交了。

而普通对象的bean只会执行业务,不会有上面的操作。

所以必须得是@Transactional实例化出的代理对象的bean。

当需要用到bean时:

spring首先是通过类型来查找Bean的,如果是多个,那么就会通过名字来查找bean(Spring使用了 Map<beanName,bean对象>的数据结构来存储已经注册的Bean ),如果是一个,那么就不需要通过名字查找了。

上面那个名字beanName,比如:

@Component
public class OrderService{ //beanName为orderService
​
}

如果两个bean的 类型 和 beanName 都相同:

  • 如果允许覆盖:就是@Bean产生的bean会覆盖@Component

  • 如果不允许覆盖:就会报错

小扩展——声明bean的注解:

  • @Component:@Component 是一个通用的注解,用于将一个类标识为 Spring 管理的组件(Bean)。它可以应用于任何类,包括普通的 POJO 类、服务类、数据访问类等。

  • @Service:@Service 注解用于将一个类标识为服务层组件,通常用于表示业务逻辑的实现类。

  • @Repository:@Repository 注解用于将一个类标识为数据访问层组件,通常用于表示数据访问对象(DAO)。

  • @Controller:@Controller 注解用于将一个类标识为控制器组件,通常用于处理用户请求和控制应用程序的流程。

  • @Configuration:@Configuration 注解用于将一个类标识为配置类,该类通常包含了用 @Bean 注解声明的方法,用于配置和创建 Bean。

@Aspect不结合@Component会怎么样?

简称切面Bean,无法将切面类注册到Spring容器中,从而无法使用切面功能。

  • 57
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值