@DependsOn
1. 说明
@DependsOn
注解是Spring中提供的一个指定Spring创建Bean的依赖顺序的注解。例如,在Spring中需要创建A对象和B对象,可以使用@DependsOn注解指定创建A对象时依赖B对象,此时,在Spring中就会先创建B对象,然后再创建A对象。
2. 场景
@DependsOn
注解主要用于指定当前Bean对象所依赖的其他Bean对象。Spring在创建当前Bean之前,会先创建由@DependsOn注解指定的依赖Bean,在Spring中使用@DependsOn注解的场景通常会有以下几种场景:
(1)在某些情况下,Bean不是通过属性
或构造函数参数
显式依赖于另一个Bean的,但是却需要在创建一个Bean对象之前,需要先创建另一个Bean对象,此时就可以使用@DependsOn注解。
(2)在单例Bean的情况下@DependsOn
既可以指定初始化依赖顺序,也可以指定Bean相应的销毁执行顺序。
(3)@DependsOn注解可标注到任何直接或间接带有@Component注解的Bean或标注到@Bean注解的方法上,可以控制Bean的创建、初始化和销毁方法执行顺序。
(4)观察者模式可以分为事件,事件源和监听器三个组件,如果在Spring中需要实现观察者模式时,就可以使用@DependsOn注解实现监听器的Bean对象在事件源的Bean对象之前被创建。
3. 源码
/**
* @author Juergen Hoeller
* @since 3.0
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
//表示指定的Bean的唯一标识,被指定的Bean会在Spring创建当前Bean之前被创建。
String[] value() default {};
}
4. Demo
假设我们有一个系统,其中包含两个组件:DatabaseService
和 CacheService
。CacheService
需要在 DatabaseService
完成初始化之后再初始化,因为 CacheService
可能会从数据库中加载一些初始数据到缓存中。
- DatabaseService.java
package com.example.demo;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
@Service
public class DatabaseService {
public DatabaseService() {
System.out.println("Initializing DatabaseService");
}
public void fetchData() {
System.out.println("Fetching data from the database...");
}
}
- CacheService.java
package com.example.demo;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
@Service
@DependsOn("databaseService")
public class CacheService {
private final DatabaseService databaseService;
@Autowired
public CacheService(DatabaseService databaseService) {
this.databaseService = databaseService;
System.out.println("Initializing CacheService");
preloadCache();
}
private void preloadCache() {
System.out.println("Preloading cache with data from the database...");
databaseService.fetchData();
}
}
- 主应用程序
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(DemoApplication.class, args);
// 获取CacheService Bean,触发初始化过程
CacheService cacheService = context.getBean(CacheService.class);
}
}