1. Spring底层核心原理解析

Spring底层核心原理解析

copy
// AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); // ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

Bean的生命周期-->

UserService.class-->无参构造方法-->普通对象-->依赖注入/加注解的属性赋值-->初始化前-->初始化-->初始化后-->bean

1、构造方法 --> 推断构造方法

​ 默认无参default

(1)有一个构造-->直接用

(2)多个有参-->不知道用哪个,找默认-->找不到报错 --> 用哪个加上@Autowried

(3)有参构造的参数传入-->从容器中找到传入

copy
pubic UserService(OrderServie orderService){ this.orderService = orderService; sout("2"); }

根据byType类型OrderServie去容器中找该类型的Bean

​ 找到多个同类-->根据名字byName确认该用哪个Bean,都不符合-->报错

​ 只有一个-->直接用

2、如何判断字段加了@Autowried/@Resource

​ -->fori fild in class.getFileds()

​ 属性赋值先byType再byName

3、初始化前调用某方法在Bean初始化前操作

copy
@PostConstructor void a(){ }

fori class getDeclared --> isAnnotationPresent --> invoke

4、初始化 --> 实现InitializingBean

copy
public void afterProperlySet() throes Excption{ }

判断对象是否实现该接口instanceof-->强转执行接口的方法afterProperlySet

4、初始化后AOP

判断:切面也是bean-->找到所有的切面bean-->遍历所有切面bean-->遍历含有注解的方法-->能对应表达式、缓存-->执行aop

需要AOP-->产生代理对象-->代理对象成为Bean

copy
@Aspect @Component public class CustomAspect{ @Before("切点") public void atBefore(JoinPoint joinPoint){ //逻辑 } } public class UserService{ @Autowired private OrderService orderService; //切点 public void test(){ //逻辑 } } @Component public class OrderService{} //执行 UseService userService = context.getBean("userService"); userService.test();

代理对象中为何没有orderService值

image-20231005162535390

5、事务

copy
//事务管理器 @Configuration public class AppConfig { @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/mydb"); dataSource.setUsername("username"); dataSource.setPassword("password"); return dataSource; } @Bean public DataSourceTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } }

(1)判断方法是否存在注解

(2)存在则利用事务管理器新建连接

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

(4)执行target.test()

(5)执行完后每一场提交,否则回滚

copy
@Transactional public void performTransactionalOperation() { // 在这里执行需要事务管理的操作 repository.save(someEntity); }

6、事务失效

image-20231005193713060

image-20231005193821097

image-20231005194012890

​ a()方法被userService调用,即被普通方法调用

​ 解决方法

​ -->新建一个UserServiceBase写a()方法,将userServiceBase注入(@Autowired)进来,由于UserServiceBase有注解,所以容器中是代理对象,当依赖注入时候从容器拿的代理对象

image-20231005194321902

​ -->注入自己

​ 自己开了事务在容器中会有自己的代理对象 userService.a();

copy
@Autowired private UserService userService;

7、@Configuration生成AppConfig的代理对象

​ 不加@Configuration注解导致在JDBCTemplate中的dataSource和事务管理器中的dataSource不是同一个

​ 原理-->

​ Appconfig的bean放到容器中,当容器中存在直接拿过来用

image-20231005195446238

image-20231005195602299

posted @   Purearc  阅读(32)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
🚀