[英]Spring dependency @PostConstruct
Say I have this dependency in a Spring @Configuration
:假设我在 Spring
@Configuration
有这个依赖项:
@Bean
public SomeClass someClass(SomeClass1 someClass1, SomeClass2 someClass2, ...) {
return new SomeClass(someClass1, someClass2, ...);
}
Say I want do do something in @PostConstruct
that includes someClass
dependency:假设我想在
@PostConstruct
中做一些包含someClass
依赖的事情:
@PostConstruct
public void init() {
someClass.doSomething();
}
This cannot be injected:这不能注入:
@PostConstruct
public void init(SomeClass someClass) {
someClass.doSomething();
}
causes:原因:
Caused by: java.lang.IllegalStateException: Lifecycle method annotation requires a no-arg method: ...
This cannot be autowired in the same config like this:这不能像这样在同一个配置中自动装配:
@Autowire
private SomeClass someClass;
@Bean
public SomeClass someClass(SomeClass1 someClass1, SomeClass2 someClass2, ...) {
return new SomeClass(someClass1, someClass2, ...);
}
as that leads to:因为这会导致:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'globalBus': Requested bean is currently in creation: Is there an unresolvable circular reference?
A config can be split (so @Bean
goes to the other config) and @Import
-ed by this one and it works OK.一个配置可以分割(所以
@Bean
转到其他配置)和@Import
-ed通过这一个,它的工作原理确定。 Probably other solutoins exist - eg creating a separate initialization bean or so.可能存在其他解决方案 - 例如创建一个单独的初始化 bean 左右。
Is there a way to do this within one @Configuration
?有没有办法在一个
@Configuration
做到这一点?
Edit编辑
As requested by @SotiriosDelimanolis, a sscce for the exception when using @Autowired
:根据@SotiriosDelimanolis 的要求,使用
@Autowired
时出现异常的sscce :
public class ConfigPostConstructDependenciesPrb {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
ctx.getBean(Service.class);
ctx.close();
}
public static class Service {
private final Dependency dependency;
public Service(Dependency dependency) {
this.dependency = dependency;
}
public void work() {
System.out.println(dependency.getNum());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Service [dependency=");
sb.append(dependency);
sb.append("]");
return sb.toString();
}
}
public static class Dependency {
private final int num;
public Dependency(int num) {
this.num = num;
}
public int getNum() {
return this.num;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("SomeClass1 [num=");
sb.append(num);
sb.append("]");
return sb.toString();
}
}
@Configuration
public static class BaseConfig {
@Autowired
private Service service;
@Bean
public Dependency dependency() {
return new Dependency(42);
}
@Bean
public Service service(Dependency dependency) {
return new Service(dependency);
}
@PostConstruct
public void init() {
service.work();
}
}
@Configuration
@Import(BaseConfig.class)
public static class Config {
@Autowired
private Service service;
}
}
Try this way:试试这个方法:
public class ConfigPostConstructDependenciesPrb {
public static void main(String[] args) {
try {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(BaseConfig.class);
ctx.registerShutdownHook();
ctx.getBean(Service.class);
ctx.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
@Configuration
class BaseConfig {
@Autowired
private Service service;
@Bean
public Dependency dependency() {
return new Dependency(42);
}
@Bean
public Service service(Dependency dependency) {
return new Service(dependency);
}
@PostConstruct
public void init() {
this.service.work();
}
}
class Dependency {
private int num;
public Dependency() {
}
public Dependency(int num) {
this.num = num;
}
public int getNum() {
return this.num;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("SomeClass1 [num=");
sb.append(num);
sb.append("]");
return sb.toString();
}
}
class Service {
private Dependency dependency;
public Service() {
}
public Service(Dependency dependency) {
this.dependency = dependency;
}
public void work() {
System.out.println(dependency.getNum());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Service [dependency=");
sb.append(dependency);
sb.append("]");
return sb.toString();
}
}
(Tested in Spring 4.3.6) (在 Spring 4.3.6 中测试)
Create a nested class inside your @Configuration and put there declarations of @Autowired service
and @PostConstruct init()
:在 @Configuration 中创建一个嵌套类,并在那里放置
@Autowired service
和@PostConstruct init()
:
@Configuration
public static class BaseConfig {
//...
@Bean
public Service service(Dependency dependency) {
return new Service(dependency);
}
@Configuration
public static class Setup {
@Autowired
private Service service;
@PostConstruct
public void init() {
service.work();
}
}
}
Below is your full example updated accordingly.以下是相应更新的完整示例。
Notice that you don't have to add explicit reference to BaseConfig.Setup
(look at the @Import
annotation before Config
class - it only refers to BaseConfig
itself).请注意,您不必明确提及
BaseConfig.Setup
(看看@Import
之前注释Config
类-它只是指BaseConfig
本身)。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.*;
import javax.annotation.PostConstruct;
public class ConfigPostConstructDependenciesPrb {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
ctx.getBean(Service.class);
ctx.close();
}
public static class Service {
private final Dependency dependency;
public Service(Dependency dependency) {
this.dependency = dependency;
}
public void work() {
System.out.println(dependency.getNum());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Service [dependency=");
sb.append(dependency);
sb.append("]");
return sb.toString();
}
}
public static class Dependency {
private final int num;
public Dependency(int num) {
this.num = num;
}
public int getNum() {
return this.num;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("SomeClass1 [num=");
sb.append(num);
sb.append("]");
return sb.toString();
}
}
@Configuration
public static class BaseConfig {
@Bean
public Dependency dependency() {
return new Dependency(42);
}
@Bean
public Service service(Dependency dependency) {
return new Service(dependency);
}
@Configuration
public static class Setup {
@Autowired
private Service service;
@PostConstruct
public void init() {
service.work();
}
}
}
@Configuration
@Import(BaseConfig.class)
public static class Config {
@Autowired
private Service service;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.