@lazy注解处理循环注入问题


@Service
public class A extends GenericBaseService {
@Autowired
private B b;
}
@Service
public class B extends GenericBaseService {
@Autowired
private A a;
}


spring中的bean和java对象的区别:
假如有个类Student,对于java对象 Student st=new Student();
但对于bean: 创建出java对象后还要经过一系列的处理器处理,如是否需要动态代理,是否需要注入各种属性


spring底层是支持循环依赖的,A依赖B B依赖A,这里说的A和B都是spring bean;
如果把bean的创建过程简述为2个步骤的话: 1. 创建 一个对象(底层通过反射) 2. 给对象注入属性,那么A和B的创建流程如下
1. A的创建: A a=new A();
2. 属性注入:发现需要B
3. 创建B b=new B();
4. 属性注入: 发现需要A,此时A已经创建了.只是还没经过各种后置处理器处理,所以B是可以完成属性注入的,只是一个半成品
5.之后回到第2步,就可以给A赋值了,循环依赖到此解决


//然而生产中的情况复杂多,相互依赖的关系网太复杂了,所以经常还是会出现提示循环依赖的异常,此时可以用另外一个方式去解决,那就是@Lazy注解了


@Service
public class A extends GenericBaseService {
@Autowired
@Lazy
private B b;
}


加了lazy的原理如下:
1. A的创建: A a=new A();
2. 属性注入:发现需要B,查询字段b的所有注解,发现有@lazy注解,那么就不直接创建B了,而是使用动态代理创建一个代理类B
3. 此时A跟B就不是相互依赖了,变成了A依赖一个代理类B1,B依赖A


验证这个方式很简单:
从容器中分别获取A a 和B b 的实例对象,然后从A中获取它依赖的对象b1,打印b1的class对象,判断b1是否和b相等

 //下面使用Student和School类来测试
@Component
public class School {
	@Autowired
	@Lazy
	private Student student;

	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}
}
@Component
public class Student {

	@Autowired
	private School school;

	public School getSchool() {
		return school;
	}

	public void setSchool(School school) {
		this.school = school;
	}
}
public class APP {
	public static void main(String[] args) throws InterruptedException {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Configurate.class);
		School school =(School) applicationContext.getBean("school");
		Student student =(Student) applicationContext.getBean("student");
		System.out.println(school.getClass());//class com.aop.School
		System.out.println(student.getClass());//class com.aop.Student
		System.out.println(school.getStudent()==student);//false
		System.out.println(school.getStudent().getClass());//class com.aop.Student$$EnhancerBySpringCGLIB$$834812b7


	}

}

 底层源码:

 

 跟到后面可以看到创建了cglib动态代理:

  




原文地址:https://www.cnblogs.com/yangxiaohui227/p/10523025.html