spring循环依赖笔记

原文链接:https://blog.youkuaiyun.com/java_lyvee/article/details/101793774

spring在默认单例的情况下是支持循环引用的
代码如下:

@ComponentScan("com.my")
public class AppConfig {}
@Component
public class IndexService {

	@Autowired
	UserService userService;

	public IndexService() {
		System.out.println("Constructor from IndexService");
	}

//	public void getUserService(){
//		System.out.println(userService);
//	}

	//生命周期的回调初始化方法注解
	@PostConstruct
	public void aa(){
		System.out.println("init");
	}
@Component
public class UserService {

	@Autowired
	IndexService indexService;

	public UserService() {
		System.out.println("UserService");
	}
}

IndexService和UserService即为两个相互依赖的类,就是循环依赖

public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
//		ac.getBeanDefinitionNames();
//		System.out.println(ac.getBean(UserService.class));
		/**
		 * 扫描scan
		 * parse 解析类
		 * 调用扩展
		 * 遍历map,validate验证
		 * new
		 */
		/*for (){
			GenericBeanDefinition genericBeanDefinition = new GenericBeanDefinition();
			genericBeanDefinition.setBeanClass(IndexService.class);
			genericBeanDefinition.setBeanClassName("beanName");
			//设置模式(例如单例还是原型)
			genericBeanDefinition.setScope("prototype");
			map.put("beanName",genericBeanDefinition);
			List<String>.add("beanName");
		}*/
		IndexService indexService = ac.getBean(IndexService.class);
//		indexService.getUserService();
		System.out.println(indexService);
	}
@Component
public class MyBeanFactoryPostprocessor implements BeanFactoryPostProcessor {
	//自定义扩展修改Bean
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//		GenericBeanDefinition indexService = (GenericBeanDefinition)beanFactory.getBeanDefinition("indexService");
//		indexService.setBeanClass(UserService.class);
	}
}

spring的循环依赖其实是可以关闭的,spring提供了api来关闭循环依赖的功能。当然你也可以修改spring源码来关闭这个功能,
我在AnnotationConfigApplicationContext的构造方法中加了一行setAllowCircularReferences(false);结果代码异常,循环依赖失败
spring使循环依赖失效方法
循环依赖其实无非就是属性注入,或者就是大家常常说的自动注入
spring bean(以下简称bean)和对象;
1、spring bean——受spring容器管理的对象,可能经过了完整的spring bean生命周期(为什么是可能?难道还有bean是没有经过bean生命周期的?答案是有的,具体我们后面文章分析),最终存在spring容器当中;一个bean一定是个对象
2、对象——任何符合java语法规则实例化出来的对象,但是一个对象并不一定是spring bean;

spring bean的生命周期如下图:
spring bean的生命周期
上图就是spring容器初始化bean的大概过程(至于详细的过程,后面文章再来介绍);
文字总结一下:
1:实例化一个ApplicationContext的对象;
2:调用bean工厂后置处理器完成扫描;
3:循环解析扫描出来的类信息;
4:实例化一个BeanDefinition对象来存储解析出来的信息;
5:把实例化好的beanDefinition对象put到beanDefinitionMap当中缓存起来,以便后面实例化bean;
6:再次调用bean工厂后置处理器;
7:当然spring还会干很多事情,比如国际化,比如注册BeanPostProcessor等等,如果我们只关心如何实例化一个bean的话那么这一步就是spring调用finishBeanFactoryInitialization方法来实例化单例的bean,实例化之前spring要做验证,需要遍历所有扫描出来的类,依次判断这个bean是否Lazy,是否prototype,是否abstract等等;
8:如果验证完成spring在实例化一个bean之前需要推断构造方法,因为spring实例化对象是通过构造方法反射,故而需要知道用哪个构造方法;
9:推断完构造方法之后spring调用构造方法反射实例化一个对象;注意我这里说的是对象、对象、对象;这个时候对象已经实例化出来了,但是并不是一个完整的bean,最简单的体现是这个时候实例化出来的对象属性是没有注入,所以不是一个完整的bean;
10:spring处理合并后的beanDefinition(合并?是spring当中非常重要的一块内容,后面的文章我会分析);
11:判断是否支持循环依赖,如果支持则提前把一个工厂存入singletonFactories——map;
12:判断是否需要完成属性注入
13:如果需要完成属性注入,则开始注入属性
14:判断bean的类型回调Aware接口
15:调用生命周期回调方法
16:如果需要代理则完成代理
17:put到单例池——bean完成——存在spring容器当中

spring在AbstractApplicationContext#finishBeanFactoryInitialization方法中完成了bean的实例化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值