假设我在Spring @Configuration
中有这种依赖关系:
@Bean
public SomeClass someClass(SomeClass1 someClass1, SomeClass2 someClass2, ...) {
return new SomeClass(someClass1, someClass2, ...);
}
说我想在@PostConstruct
中做一些包含someClass
依赖的事情:
@PostConstruct
public void init() {
someClass.doSomething();
}
这不能注入:
@PostConstruct
public void init(SomeClass someClass) {
someClass.doSomething();
}
导致:
Caused by: java.lang.IllegalStateException: Lifecycle method annotation requires a no-arg method: ...
这不能在同一个配置中自动装配:
@Autowire
private SomeClass someClass;
@Bean
public SomeClass someClass(SomeClass1 someClass1, SomeClass2 someClass2, ...) {
return new SomeClass(someClass1, someClass2, ...);
}
因为这导致:
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?
配置可以拆分(所以@Bean
转到另一个配置)和@Import
- 由此编辑,它可以正常工作。可能存在其他溶剂 - 例如创建一个单独的初始化bean。
有没有办法在一个@Configuration
内执行此操作?
修改
根据@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;
}
}
答案 0 :(得分:0)
尝试这种方式:
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();
}
}
答案 1 :(得分:0)
(在Spring 4.3.6中测试)
在@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();
}
}
}
下面是相应的完整示例。
请注意,您不必添加对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;
}
}