闲散小计-Spring

IOC容器的初始化流程和getBean的流程

加载流程

ioc容器先加载xml文件,解析所有<bean>标签,并把每一个<bean>标签都封装成一个对象(beanDefination:仅仅是一个描述对象,记录这个类相关的信息),在解析完成后进行初始化,创建单例的bean存放在SinletonObjects中

getBean时

使用getBean(对象在ioc的名称),

先去单例对象集合SinletonObjects中找(找到直接返回对象),

如果没有就去beanDefination找

(找对应的对象的描述,根据scope的值

如果是多例:直接调用createBean(利用反射把对象创建返回)---》容器不会维护,每一次创建都是新的对象

如果是单例:利用反射把对象,创建后存储到单例集合(SinletonObjects)一份再返回对象)

都没有就报异常NoSuchBeanDefinationException,

IOC容器初始化流程

IOC容器getBean的具体流程

SpringBean的配置方式

xml文件形式(ClassPathXmlApplicationContext)

注解(AnnotationConfigApplicationContext)

基于Java类+配置注解的方式(@Configuration @Bean)

IOC容器Bean的作用域

依赖注入的三种方式

set注入

构造器注入

注解注入

Spring常用注解

  • @ComponentScan 组件扫描,扫描指定包下的@Component @Controller @Repository
  • @Controller 标记当前类为容器对象,代表 控制层 组件
  • @Repository 标记当前类为容器对象,代表 持久层 组件
  • @Service 标记当前类为容器对象,代表 服务层 组件
  • @Component 标记当前类为容器对象,代表 组件

ps:@Controller @Repository @Service @Component 四个注解均代表组件的意思,@Controller @Repository @Service三个注解均继承了@Component,只是用来区分不同层级

  • @Autowired 自动装配注解,默认按类型装配
  • @Transactional 事务注解
  • @Value 将配置文件中的值注入到指定字段中
  • @Bean 配置bean对象,作用与<bean>标签一致
  • @Configuration 标记当前java类是一个配置类

@Autowrite 和@Resoure 的区别

@Autowired:

按照类型去容器找 (spring提供的注解)

会存在问题,当容器中同类型的对象有多个时,会报错

而此时需要配合@Qualifier一起使用,改为根据bean名称去找

@Resoure :

按照bean名称去容器找 (JDK自带的注解)

而@Resoure 本身就是根据名称去找,自然不会存在上述问题

springBean同名的覆盖问题

可以在设置中设置不允许覆盖(此时如果有同名bean,会报错)

循环依赖问题

IOC容器默认解决 scope为单例的循环依赖问题(三级缓存)

springBean的生命周期

简化版

详细版(单例对象是十一步,多例对象9步(因为ioc容器不存储))

以运行以下方法为例

代码:

xml文件

运行过程示例

  • IOC容器利用反射调用对象无参构造创建新对象  

  • 通过set方法给对象设置属性

  • 如果有需要,可以实现BeanNameAware来获得对象名称

  • 如果有需要,可以实现ApplicationContextAware来获得容器,以此来获取容器中的bean对象,进行统一的处理

  • 实现BeanPostProcessor的类称为统一Bran的后置处理器,先执行postProcessBeforeInitialization(可以统一在执行初始化之前的操作)

  • 实现InitializingBean接口中的afterPropertiesSet方法可以在初始化后对我们的类做一些处理 例如缓存

  • 执行自己配置的初始化方法

  • 实现BeanPostProcessor的类称为统一Bran的后置处理器,执行postProcessAfterInitialization(可以统一在执行初始化之后的操作)

  • 执行对象本身的业务方法

  • 执行spring对象本身的销毁方法先执行(实现接口的方法)

  • 自己配置的方法后执行

SpringAOP

简单理解

面向切面编程

实际应用场景

定义切面类

加上注解:@Aspect @Component

AOP工作原理

默认JDK,可切换CGLIB

Spring事务

spring事务的配置方式

springBoot事务

spring事务的隔离级别

spring事务的失效场景

  1. 数据库引擎不支持事务
  2. 没有被spring管理
  3. 方法不是public
  4. 自身调用问题--》方法a调用方法b,事务注解在方法b中
  5. 数据源未配置事务管理(现在springBoot默认配置,不会出现这个问题)
  6. 在传播行为中设置了不支持事务
  7. 异常被捕获了 (try {} catch{})
  8. 异常类型错误,默认捕获的是RuntimeException

--》解决办法:把异常捕获范围加大

Spring事务的传播行为(两个有事务的方法相互调用)

分类(七种):

PROPAGATION_REQUIRED
表示当前方法必须在一个具有事务的 上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。( 如果被调用端发生异常,那么调用端和被调用端事务都将回滚)
PROPAGATION_REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。
PROPAGATION_SUPPORTS
表示当前方法不必需要具有一个事务 上下文,但是如果有一个事务的话,它也可以在这个事务中运行
PROPAGATION_MANDATORY
表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
PROPAGATION_NOT_SUPPORTED
总是非事务地执行,并挂起任何存在的事务。
PROPAGATION_NEVER
总是非事务地执行,如果存在一个活动事务,则抛出异常
PROPAGATION_NESTED
表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中 ,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同propagation. required的一样

Spring中的事务设置可以设置传播行为,用来控制方法调用过程中事务的传播方式,包括:

  1. REQUIRED:表示当前方法必须运行在事务中,如果当前存在事务,则加入该事务,否则创建新的事务。
  2. SUPPORTS:表示当前方法不需要事务上下文,如果当前存在事务,则在该事务中执行,否则继续在非事务性上下文中执行。
  3. MANDATORY:表示该方法必须在事务中执行,如果当前存在事务,则在该事务中执行,否则抛出异常。
  4. REQUIRES_NEW:表示当前方法必须运行在它自己的事务中。如果当前存在事务,则挂起该事务,创建新的事务,执行完后再将挂起的事务恢复执行。
  5. NOT_SUPPORTED:表示该方法不应运行在事务上下文中,如果当前存在事务,则挂起该事务,执行完后再将挂起的事务恢复执行。
  6. NEVER:表示该方法不应该运行在事务上下文中,如果当前存在事务,则抛出异常。
  7. NESTED:表示该方法必须运行在它自己的嵌套式事务中,并且这个嵌套式事务是被外部事务所驱动的。
    根据实际业务需求选择合适的传播行为可以更加灵活地处理事务,提高系统性能和代码健壮性。

常用的两种

PROPAGATION_REQUIRED
表示当前方法必须在一个具有事务的 上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。( 如果被调用端发生异常,那么调用端和被调用端事务都将回滚)

下图:方法a开启事务,调用方法b时出现异常,方法b跟着方法a回滚


PROPAGATION_REQUIRES_NEW
总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。

下图:方法a开启事务,调用方法b时方法b新开事务,b完成后提交,此时出现异常,仅方法a回滚

以上均为个人见解,侵删

有不对的或者还有遗漏的欢迎各位大佬补充,致谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值