@PostConstruct 的执行顺序
Execution Order of @PostConstruct
我的 JEE 应用程序中有 2 个单例,我想在启动时对其进行初始化。像这样:
@Singleton
@Startup
public class ServiceB {
@EJB
private ServiceA a;
@PostConstruct
private void init() {
....
}
}
ServiceB 并不真正需要 ServiceA,我只是添加了依赖项以确保 ServiceA 在 ServiceB 的 init() 方法开始之前完全初始化(阅读:@PostConstruct-method finished)。
但它不会等待。 ServiceB 实际上在ServiceA 之前启动。
有没有办法确保一个 Bean 的 @PostConstruct- 方法等待另一个 Bean 的 @PostConstruct-method 完成?
我知道我可以删除 ServiceA 中的 @PostConstruct 注解并直接从 ServiceB 中调用它
@PostConstruct init() {
a.init();
}
但我有没有 ServiceB 的部署。所以我不能依赖 ServiceB 来初始化 ServiceA。 ServiceA 必须自己做。并且 ServiceB 必须等待 ServiceA 完成它。
使用 @DependsOn 注释声明对启动 bean 的初始化依赖性。
示例:
@Singleton
@Startup
public class ServiceA {
@PostConstruct
public void init() { ... }
}
@Singleton
@Startup
@DependsOn("ServiceA")
public class ServiceB {
@EJB
ServiceA a;
@PostConstruct
public void init() { ... } // will be called after a is initialized
}
关于@DmiN给出的答案的问题
(我是新用户,所以无法 post 直接发表评论)
根据您的建议(如下代码所示)-- 我同意服务B 将在服务A 初始化后启动(只是初始化,而不是post构造完成)。但是我怀疑是否可以保证ServiceB的init方法永远不会运行除非ServiceA的PostConstruct方法已经执行完毕?正确吗?
@Singleton
@Startup
public class ServiceA {
@PostConstruct
public void init() { ... }
}
@Singleton
@Startup
@DependsOn("ServiceA")
public class ServiceB {
@EJB
ServiceA a;
@PostConstruct
public void init() { ... } // will be called after a is initialized
}
@PostConstruct注解用于依赖注入完成后执行的方法,所以到这里服务A在服务B中的注入就完成了,然后就可以执行服务B的init函数了
public class ServiceA {
@PostConstruct
public void init() { }
}
public class ServiceB {
@Autowired
ServiceA a;
@PostConstruct
public void init() { }
}
作为一种简单的替代解决方案,您可以在一个地方手动收集所有应按定义顺序初始化的独立 bean。它有助于避免 @DependsOn
public interface OrderedPostConstruct {
void init();
}
// ==== Production ====
@Configuration
public class InitConfig {
private final ObjectProvider<OrderedPostConstruct> initializers;
@PostConstruct
public void initEntryPoint() {
initializers.orderedStream().forEach(Initialize::init);
}
}
@Order(1)
@Component
public class OneUsefullComponent implements OrderedPostConstruct {
@Override
public void init() {
// executed first
}
}
@Order(2)
@Component
public class TwoUsefullComponent implements OrderedPostConstruct {
@Override
public void init() {
// executed second
}
}
// ==== Integration tests ====
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class TestDataPopulator implements OrderedPostConstruct {
@Override
public void init() {
// populate data for tests
}
}
我的 JEE 应用程序中有 2 个单例,我想在启动时对其进行初始化。像这样:
@Singleton
@Startup
public class ServiceB {
@EJB
private ServiceA a;
@PostConstruct
private void init() {
....
}
}
ServiceB 并不真正需要 ServiceA,我只是添加了依赖项以确保 ServiceA 在 ServiceB 的 init() 方法开始之前完全初始化(阅读:@PostConstruct-method finished)。
但它不会等待。 ServiceB 实际上在ServiceA 之前启动。
有没有办法确保一个 Bean 的 @PostConstruct- 方法等待另一个 Bean 的 @PostConstruct-method 完成?
我知道我可以删除 ServiceA 中的 @PostConstruct 注解并直接从 ServiceB 中调用它
@PostConstruct init() {
a.init();
}
但我有没有 ServiceB 的部署。所以我不能依赖 ServiceB 来初始化 ServiceA。 ServiceA 必须自己做。并且 ServiceB 必须等待 ServiceA 完成它。
使用 @DependsOn 注释声明对启动 bean 的初始化依赖性。
示例:
@Singleton
@Startup
public class ServiceA {
@PostConstruct
public void init() { ... }
}
@Singleton
@Startup
@DependsOn("ServiceA")
public class ServiceB {
@EJB
ServiceA a;
@PostConstruct
public void init() { ... } // will be called after a is initialized
}
关于@DmiN给出的答案的问题 (我是新用户,所以无法 post 直接发表评论)
根据您的建议(如下代码所示)-- 我同意服务B 将在服务A 初始化后启动(只是初始化,而不是post构造完成)。但是我怀疑是否可以保证ServiceB的init方法永远不会运行除非ServiceA的PostConstruct方法已经执行完毕?正确吗?
@Singleton
@Startup
public class ServiceA {
@PostConstruct
public void init() { ... }
}
@Singleton
@Startup
@DependsOn("ServiceA")
public class ServiceB {
@EJB
ServiceA a;
@PostConstruct
public void init() { ... } // will be called after a is initialized
}
@PostConstruct注解用于依赖注入完成后执行的方法,所以到这里服务A在服务B中的注入就完成了,然后就可以执行服务B的init函数了
public class ServiceA {
@PostConstruct
public void init() { }
}
public class ServiceB {
@Autowired
ServiceA a;
@PostConstruct
public void init() { }
}
作为一种简单的替代解决方案,您可以在一个地方手动收集所有应按定义顺序初始化的独立 bean。它有助于避免 @DependsOn
public interface OrderedPostConstruct {
void init();
}
// ==== Production ====
@Configuration
public class InitConfig {
private final ObjectProvider<OrderedPostConstruct> initializers;
@PostConstruct
public void initEntryPoint() {
initializers.orderedStream().forEach(Initialize::init);
}
}
@Order(1)
@Component
public class OneUsefullComponent implements OrderedPostConstruct {
@Override
public void init() {
// executed first
}
}
@Order(2)
@Component
public class TwoUsefullComponent implements OrderedPostConstruct {
@Override
public void init() {
// executed second
}
}
// ==== Integration tests ====
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
public class TestDataPopulator implements OrderedPostConstruct {
@Override
public void init() {
// populate data for tests
}
}