1. Spring底层核心原理解析

发布时间 2023-10-05 20:24:13作者: Purearc

Spring底层核心原理解析

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

Bean的生命周期-->

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

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

​ 默认无参default

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

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

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

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初始化前操作

@PostConstructor
void a(){

}

fori class getDeclared --> isAnnotationPresent --> invoke

4、初始化 --> 实现InitializingBean

public void afterProperlySet() throes Excption{

}

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

4、初始化后AOP

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

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

@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、事务

//事务管理器
@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)执行完后每一场提交,否则回滚

@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();

@Autowired
private UserService userService;

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

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

​ 原理-->

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

image-20231005195446238

image-20231005195602299