Java Spring依赖项@PostConstruct
假设我在SpringJava Spring依赖项@PostConstruct,java,spring,spring-java-config,Java,Spring,Spring Java Config,假设我在Spring@配置中有此依赖项: @Bean public SomeClass someClass(SomeClass1 someClass1, SomeClass2 someClass2, ...) { return new SomeClass(someClass1, someClass2, ...); } 假设我想在@PostConstruct中做一些事情,包括someClass依赖项: @PostConstruct public void init() { someCla
@配置中有此依赖项:
@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
-ed由这个配置执行,并且工作正常。可能存在其他解决方案-例如,创建一个单独的初始化bean等等
有没有一种方法可以在一个@配置中实现这一点
编辑
根据@SotiriosDelimanolis的要求,a在使用@Autowired
时出现异常:
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;
}
}
试着这样做:
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();
}
}
(在弹簧4.3.6中测试)
在@Configuration内创建一个嵌套类,并在其中声明@Autowired service
和@PostConstruct init()
:
下面是相应更新的完整示例
请注意,您不必添加对BaseConfig.Setup
的显式引用(查看Config
类之前的@Import
注释-它仅指BaseConfig
本身)
为什么不能/不可以Inject
it?是SomeClass
内部类吗?@PostConstruct是为您的bean而不是为您的配置类。正如user489041所说,如果bean正在使用它,那么您应该将它注入bean中。您必须在@Configuration
类中执行@PostConstruct
?这是什么样的设置方法?另外,根据配置的其余部分,您的@Autowired
解决方案应该可以工作。既然没有,你就有其他的干扰。请澄清。与我发布的内容相比,这里的区别是什么?删除Config
class?如果是这样的话,那并不能解决任何问题。看看修饰符,我的类不是静态的。我证明了这个例子,它是有效的。不管类是静态的还是非静态的,都不会改变任何东西(请自行测试确认)。您以更改初始化的方式更改了代码—您将配置的数量从2减少到了1,并消除了导入。如果您像我一样导入配置(即Config
importsBaseConfig
并使用Config
进行初始化),它是否有效?请告诉我测试此代码时出现了什么错误,因为我在发布之前测试了代码,它可以工作。可能是你有另一个缺点。我同意,它是有效的,但它不是做同样的事情。您删除了Config
类,并且只使用BaseConfig
。如果您尝试使用多个配置(我需要),它会中断。有关详细信息,请参阅我之前的评论。
@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();
}
}
}
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;
}
}