#通过XML方式设置bean的作用域
//通过注解方式设置bean的作用域
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DemoDAOImpl implements IDemoDAO{ }
Spring Bean的生命周期总体分为四个阶段:实例化=>属性化=>初始化=>销毁
1、实例化Bean:
根据配置文件中Bean的定义,利用Java Reflection反射技术创建Bean的实例
2、注入对象的属性值(或对象)
3、处理各种Aware接口:
Spring会检测Bean是否实现了xxxAware接口,通过Aware类型的接口,可以让Spring框架为当前Bean注入响应的内容
4 、执行BeanPostProcessor前置处理:
如果想对 Bean进行一些自定义的前置处理,那么可以让 Bean 实现了 BeanPostProcessor 接口,将会在该阶段调用 postProcessBeforeInitialization(Object obj, String s)方法。
5、 执行InitializingBean初始化方法:
如果 Bean 实现了InitializingBean 接口,执行 afeterPropertiesSet()方法。
6、执行init-method自定义初始化方法:
如果 Bean 在 Spring 配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
7、执行BeanPostProcessor后置处理:
如果这个 Bean 实现了BeanPostProcessor接口,将会调用 postProcessAfterInitialization(Object obj,String s)方法,由于这个方法是在 Bean初始化结束后调用
8、执行DisposableBean销毁Bean:
当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调用其实现的destroy()方法执行销毁;
9、执行destroy-method自定义销毁方法:
如果这个Bean的Spring 配置中配置了 destroy-method 属性,会自动调用其配置的自定义销毁方法。
循环依赖问题是指:类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。例如A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题。
为了解决循环依赖问题,Spring容器采用了以下几种策略:
三级缓存:Spring容器使用三级缓存来解决属性循环依赖。
- 第一级缓存是SingletonObjects,用于存储完全初始化的bean;
- 第二级缓存是earlySingletonObjects,用于存储已经创建但尚未初始化的bean;
- 第三级缓存是singletonFactories,用于存储用于创建bean的ObjectFatory
- 当容器遇到循环依赖时,它会尝试从第二级或第三级缓存中获取bean,而不是直接实例化它。
延迟初始化:Spring容器允许延迟初始化bean,这意味着在需要时才创建和初始化bean。这有助于避免在循环依赖的情况下过早地实例化bean。
代理对象:对于通过AOP增强的bean,Spring容器会创建一个代理对象来替代原始bean。这个代理对象负责处理循环依赖,同时保留原始bean的行为。
- @Component:通用Bean的注解,可标注任意类为Bean如果一个Bean不知道属于哪个层,可以使用@Component注解标注。
- @Repository:定义数据访问层Bean的注解。
- @Service:定义业务层Bean的注解。
- @Controller:定义控制器Bean的注解。
- @Autowired:按类型自动注入
- @Qualifier::按名称自动注入
- @Configuration:声明配置类
- @ComponentScan:组件扫描
- @EnableScheduling:任务调度
- @EnableAspectJAutoProxy:启动自动代理工程、
关键字:AOP名词解释,AOP实现原理(动态代理)
关键字:增强方式的差异(运行时、编译时),实现方式的差异(动态代理、字节码操作)
关键字: 分别介绍每种通知的实现接口,执行方式
事务传播行为是为了解决业务层方法之间互相调用时,产生事务问题。
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。
事务传播行为有如下分类:
1. TransactionDefinition.PROPAGATION_REQUIRED
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。 @Transactional
注解默认使用的事物传播行为
2. TransactionDefinition.PROPAGATION_REQUIRES_NEW
创建一个新的事务,如果当前存在事务,则把当前事务挂起。也就是说不管外部方法是否开启事务,Propagation.REQUIRES_NEW修饰的内部方法会新开启自己的事务,且开启的事务相互独立,互不干扰。
3. TransactionDefinition.PROPAGATION NESTED
如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取
值等价于TransactionDefinition.PROPAGATION_REQUIRED。
4. TransactionDefinition.PROPAGATIÓN_MANDATORY
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:代表强制性)
5. TransactionDefinition.PROPAGATION_SUPPORTS
如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
6. TransactionDefinition.PROPAGATION_NOT_SUPPORTED
以非事务方式运行,如果当前存在事务,则把当前事务挂起。
7. TransactionDefinition.PROPAGATION_NEVER
以非事务方式运行,如果当前存在事务,则抛出异常。
1. TransactionDefinition.ISOLATION_DEFAULT 默认隔离级别
使用当前数据库的默认隔离级别,MySQL 默认采用的是可重复读 REPEATABLE_READ 隔离级
别。Oracle 默认采用的是读已提交 READ_COMMITTED 隔离级别.
2.TransactionDefinition.ISOLATION_READ_UNCOMMITTED 读未提交
最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
3. TransactionDefinition.ISOLATION_READ_COMMITTED 读已提交
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
4. TransactionDefinition.ISOLATION_REPEATABLE_READ 可重复读
对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
5. TransactionDefinition.ISOLATION_SERIALIZABLE 串行化
最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读,不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。