你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
依稀记得我曾经参加过中某建筑相关公司的技术专家岗位面试,当时作为一个工作十来年的程序员,面到最后,其中一个面试官(两个面试官一起面的)问了我一个问题:Spring中的BeanA要想在BeanB之后初始化,需要怎么做?
对不起,这个问题我真的不知道,因为没有遇到过这样的场景。所以呀,其实就三个问题:
第一,八股文没有刷好;
第二,面试也是需要看运气,看你的知识面与面试官的知识面的覆盖区间的;
第三,面完出来,我某度了一下,心中一万只xxx,我想说这种题目怎么会作为面试技术专家的题目,而且还在最后问了出来。
算了,确实没有答上来,是我准备不够充分(挨打要立正)。所以最后我成功的面挂了。
其实被问到这个问题,我的第一反应是,spring不是可以解决循环依赖的问题吗?为什么还需要考虑哪个bean初始化的先后顺序呢?
先来回答面试的问题,很简单:@DependsOn注解就可以解决,当然我第一个想到的@lazy的注解,但是也并不能保证一定的在另一个的后面。
第二个问题,我们一起来深入探讨一下:
在某些情况下,@DependsOn 用于明确告诉 Spring,某些 Bean 的初始化顺序需要满足特定的要求,即便它们之间没有显式的依赖关系(即没有通过字段注入、构造函数注入等方式声明的依赖)。
比如,一个 BeanA 会在初始化时加载某些资源到内存,而另一个 BeanB 依赖这些资源的可用性,但这两个 Bean 之间并没有直接的依赖关系。
静态资源或某些 Bean 的初始化可能涉及到静态方法调用或配置加载,而这些操作需要依赖另一个 Bean 的初始化。
例如:假设有一个 ConfigBean 用于初始化一些静态配置信息,而其他 Bean 都需要这些配置才能正常工作,但它们之间没有显式的依赖关系。
全局配置初始化的场景
在这里,ServiceBean 使用了 ConfigBean 中的静态变量,但并没有直接注入 ConfigBean,所以需要通过 @DependsOn 明确指定初始化顺序。
public class ServiceBean {
public ServiceBean() {
System.out.println("ServiceBean initialized! Using static config: " + ConfigBean.CONFIG);
}
}
public class ConfigBean {
public static String CONFIG;
public ConfigBean() {
CONFIG = "Initialized Config";
System.out.println("ConfigBean initialized!");
}
}
动态代理、切面与拦截器的初始化
在某些使用动态代理、切面编程(AOP)或拦截器的场景下,代理类可能需要在目标 Bean 之前完成初始化,或者反过来。
假设一个 Bean 是动态代理生成的,另一个依赖代理类提供的功能,则可能需要通过 @DependsOn 来保证顺序。
防止懒加载导致的顺序问题
在使用懒加载(@Lazy)时,某些 Bean 可能会因为未被主动调用而延迟初始化。如果有一个 Bean 必须在容器启动时完成初始化,但它的依赖关系不是显式的,可以用 @DependsOn 强制保证初始化顺序。
解决容器外部资源的依赖
有些场景涉及到外部资源,比如数据库连接池、消息队列、缓存服务等。这些资源需要某些初始化操作才能保证后续的服务正常运行。虽然这些资源不一定直接由 Spring 管理,但可以通过 @DependsOn 间接指定依赖关系。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!