@DependsOn 设置Bean依赖 结合@Lazy 修改Bean加载顺序
一、需要@DependsOn的场景
在开发中,如果有2个类A和B,且B要监听A,则希望B在A之前加载到容器中。
但是Spring默认是根据文件夹中类名的顺序加载,例如字母A在B之前,则会先加载A。
@DependsOn注解可以设置Bean直接的依赖关系,被依赖的会先创建加载到Spring容器中。
下面举例:有一个老师类:Teacher,一个迟到学生类:LateStudent。
老师要检查哪些学生迟到,则老师得先到学校,在教室门口等着迟到的学生。
对于Spring容器而言,得先加载Teacher,后加载LateStudent,这样Teacher才能监听所有的LateStudent。
二、实验示例
1. Teacher类
@Component("teacher")
public class Teacher {
public Teacher() {
System.out.println("创建了老师");
}
}
2. LateStudent类
@Component("lateStudent")
public class LateStudent {
public LateStudent() {
System.out.println("创建了学生");
}
}
3. 配置类
Teacher ,LateStudent 都在bean包下
@Configuration
@ComponentScan(value = "bean")
public class MySpringConfig {
}
4. 测试类
public class DependsOnTest {
public static void main(String[] args) {
//创建容器
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("config");
ac.start();
}
}
运行结果:
这个不是我们想要的,但是学生类在老师类上方,所以先加载了学生
创建了学生
创建了老师
5. 添加@DependsOn,设置依赖关系
添加@DependsOn,设置依赖关系
@Component("lateStudent")
@DependsOn("teacher")
public class LateStudent {
public LateStudent() {
System.out.println("创建了学生");
}
}
运行结果:
创建了老师
创建了学生
三、用@Lazy懒加载
以前博客介绍过@Lazy,@Lazy只对单例有效。
单例Bean懒加载 @Lazy的使用和失效情况
1. 用@Lazy方式让学生在后面加载
去掉@DependsOn(“teacher”),加上@Lazy
@Lazy
@Component("lateStudent")
public class LateStudent {
public LateStudent() {
System.out.println("创建了学生");
}
}
public class DependsOnTest {
public static void main(String[] args) {
//创建容器
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("config");
Object lateStudent = ac.getBean("lateStudent");
ac.start();
}
}
结果如下
创建了老师
创建了学生
四、@DependsOn和@Lazy都存在的情况
1. 假设被依赖的Teacher用了@Lazy
此时DependsOnTest 没有调用LateStudent ,即没有下面的语句
Object lateStudent = ac.getBean("lateStudent");
老师:
@Lazy
@Component("teacher")
public class Teacher {
public Teacher() {
System.out.println("创建了老师");
}
}
学生:
@Component("lateStudent")
@DependsOn("teacher")
public class LateStudent {
public LateStudent() {
System.out.println("创建了学生");
}
}
结果如下:
创建了老师
创建了学生
结果说明老师Teacher 类上的@Lazy失效了。
因为启动容器创建LateStudent 时,发现用到Teacher,所以就先加载了Teacher,导致Teacher的 @Lazy失效了