1.了解自动布线规则以及消除歧义
自动装配,消除歧义即@Qualifier注解(指定bean对象)的使用,在多个相同类型的Bean时使用,注入@Qualifier注解修饰的名称Bean
自动布线规则
- 查找与所需类型匹配的唯一bean
- 如果提供了@Qualifer则使用规定的名称
- 根据名称查询匹配的bean
我们有多个queue bean ,spring会查找ID设置为“ack”的bean
如果一个类上有@Primary注解,那么会优先使用该Bean
@Component
public class TransferServiceImpl implements TransferService {
@Autowired
public TransferServiceImpl(AccountRepository accountRepository) { ... }
}
@Component
public class JpaAccountRepository implements AccountRepository { ... }
@Component
public class JdbcAccountRepository implements AccountRepository { ... }
当启动时:NoSuchBeanDefinitionException, no unique bean of type [AccountRepository] is defined: expected single bean but found 2...
@Component("transferService")
public class TransferServiceImpl implements TransferService {
@Autowired
public TransferServiceImpl(@Qualifer("jdbcAccountRepository")
AccountRepository accountRepository) { ... }
}
@Component("jpaAccountRepository")
public class JpaAccountRepository implements AccountRepository { ... }
@Component("jdbcAccountRepository")
public class JdbcAccountRepository implements AccountRepository { ... }
@Qualifer也适用于方法注入和属性注入。组件的名称应该不体现实现细节,除非同一个接口有2个相同的实现(如上所示)
2.对IOC的注入规则有了深层的理解
IOC的注入规则,掌握靠你告知反转,依赖注入的规则,包括@Autowired和@Resource,具体诸如规则,以及实现方式,包括ApplicationCintext的作用
@Autowired先按照类型查找,再按照名词查找。由Spring提供的注解
// 构造方法注入
@Autowired
public TransferServiceImpl(@Value("${daily.limit}") int max) {
this.maxTransferPerDay = max;
}
//方法注入
@Autowired
public void setDailyLimit(@Value("${daily.limit}") int max) {
this.maxTransferPerDay = max;
}
//字段注入
@Value("${daily.limit}")
int maxTransfersPerDay;
@Resource,先按照名称查找再按照类型查找,支持Setter和字段注入,由JSR-250提供
//Setter注入
@Resource(name="jdbcAccountRepository")
public void setAccountRepository(AccountRepository repo) {
this.accountRepository = repo;
}
//字段注入
@Resource(name="jdbcAccountRepository")
private AccountRepository accountRepository;
@Autowired来自Spring,可能不支持其他框架 | @Resource来自JSR-250,支持大部分框架 |
默认按类型注入byType | 默认按名字注入byName |
@Autowired只有一个参数 required表示是否开启自动注入 | @Resource包含七个参数 最重要的时name和type自动装配 |
可以和@Qualifier组合使用,确定某个bean | @Resource指定name,按照名字装配,指定type按照type装配 |
可以用在构造器,方法,参数,成员变量,注解上 | 只能用在类,成员变量,方法上 |
@Autowired的装配顺序如下:
@Resource的装配顺序如下:
3.spring的生命周期
Bean 的生命周期,后处理Bean,实例化Bean,Bean的后处理,精通bean的初始化过程,以及@PropertySource以及@PostConstruct的自定义
创建:
- bean的定义(BFPP加载并处理Bean的定义)
- bena的实例化(存放在三级缓存里,需要被注入的对象会从三级缓存转移到二级缓存中)
- bean的属性注入(存放在一级缓存,在此阶段结束后可以使用@PostConstruct)
- 如果bean实现了BeanNameAware接口。则调用setBeanName()方法。如果bean实现了BeanFactoryAware接口,则调用setBeanFactory()方法。如果实现了ApplicationContextAware接口,则调用setApplicationContext()方法
- 如果bean实现了BPP接口,调用其预处理方法
- 调用init-method方法
- 如果bean实现了BPP接口,调用其后处理方法
使用:
- 从IOC容器ApplicationContext获取Bean对象,
- spring使用反射创造代理对象操作bean,你的Bean被代理包裹,在初始化BPP的阶段创建
- spirng会通过Proxy,jdk接口,CGLib代理创建代理对象,在对象的基础上使用代理操作对象
- spring默认使用Proxy进行代理,springboot默认使用CGLib进行代理
销毁:
这里可以使用@ProDesTroy注解(销毁之前)
当bean不再被需要时,会经过清理阶段,Bean如果实现了DisposableBean这个接口,那么会调用对应的destroy()方法;
4.SpringBoot的自动配置,元注解
SpringBoot的自动配置,@SpringBootApplication的元注解和@Conditional注解的使用
@SpringBootConfiguration标注这是一个配置类
@EnableAutoConfiguration自动配置
@AutoConfigurationPackage启动自动配置包扫描的路径,开启包扫描机制
@Import(**)抽取第三方jar包,信息,进行自动配置。
@AutoConfigurationPackage自动扫描
5.AOP的概念
5中Advice的使用,切入点Execution表达式,切入点的使用方法,基于AspectJ
spring的AOP代理的底层是动态代理
- JDK Proxy代理,只能代理继承接口的类,不能针对普通类,Java自带,调用简单
- CGLib通过子类的方式完成调用,来自于第三方提供的工具,基于ASM实现,高性能
核心AOP的概念
连接点:程序执行过程中的点,需要执行AOP的具体类的位置
切入点:一个或多个连接点的表达式。多个切入点的集合表达式
Advice:需要切入的逻辑,每个连接点执行的代码
切面:一个囊括了切入点和Advice的模块
编制:将主要代码与界面进行结合的技术
切面是如何应用的?
- 请求从前端进入后端进行处理
- 代理实现目标接口
- 被springaop的拦截
- 执行切面的逻辑
- 调用目标方法
6.了解切片测试,springboot的相关测试
Web分片测试
禁用全部自动配置,之应用与MVC测试相关的配置,通过@WebMvcTest与@MockBean结合使用,模拟依赖关系
@MockBean来自Spring boot框架,当需要上下文时使用它,不存在模拟Bean,创建模拟Bean;或用模拟Bean替换一个Bean
@WebMvcTest(AccountController.class)
public class AccountControllerBootTests {
@Autowired
private MockMvc mockMvc;
@MockBean
private AccountManager accountManager;
@Test
public void testHandleDetailsRequest() throws Exception {
// Test code
}
}
存储库分片测试
使用DataJpaTest进行存储库切片测试
- 可用于测试只关注JPA组件的情况下
- 自动配置TestEntityManager
- 使用了一个嵌入式内存数据库
Spring boot的相关测试
以Spring的方式进行测试
相关注解
@SpringBootTest @WebMcvTest @WebFluxTest
@DataJpaTest @DataJdbcTest @JdbcTest @DataMobgoTest @DataRedisTest
7.Spring的事务管理
使用@Transactional或者TransactionTemplate(需要时直接注入)配置事务。@Transaction可以写在类和方法上,适用于接口声明的所有方法
@Autowired
private TransactionTemplate transactionTemplate;
...
public void save(final User user) {
queryData1();
queryData2();
transactionTemplate.execute((status) => {
addData1();
updateData2();
return Boolean.TRUE;
})
}
事务的四大原则 ACID
原子性 每个事务都是不可分割的,要么全部成功,要么全部失败
一致的 用不违背数据库完整性的约束,事务的修改前后,数据库的完整性保持一致
隔离性 彼事物之间彼此相互隔离,正在执行的事务不会干扰另一个事务的数据
持久性 提交数据的改变是永久性的
事务的并发问题
脏读:读取到的数据进行了更变,此时读取的数据就是脏数据
不可重复读:多次读取数据的情况下,读取的数据进行了更变,多次读取的结果不一致。
幻读:执行操作的时候,进行了增加数据,导致读取的结果与预期不符
事务的隔离级别
读未提交,可重复读,不可重复读,串行化
Spring整合了全局或本地事务,使用相同的API
- 从本地到全局的变化不大
- 只改变了事务管理器
事务的传播级别
传播类型 | 如果没有事务 | 如果有事务 |
MANDATORY | 抛出异常 | 使用当前事务 |
NEVER | 不创建事务,以非事务状态运行 | 抛出异常 |
NOT_SUPPORTED | 不创建事务,以非事务状态运行 | 挂起事务,非事务状态运行 |
SUPPORTS | 不创建事务,以非事务状态运行 | 使用当前事务 |
REQUIRED 默认 | 创建新的事务 | 使用当前事务 |
REQUIRED_NEW | 创建新的事务 | 挂起事务,以新事物运行 |
NESTED | 创建新的事务 | 创建新的内嵌事务 |