Java SpringBean不是自动连线的
我对SpringbeanJava SpringBean不是自动连线的,java,spring,inversion-of-control,Java,Spring,Inversion Of Control,我对SpringbeanDefaultConfigurationService初始化有一个问题,它是从abstract类扩展而来的。我完全卡住了 等级划分如下: public interface ConfigurationService { TaxPayer getTaxPayer(); } 此类对于需要初始化的服务非常有用: public abstract class BaseInitializationAwareService { private boolean ini
DefaultConfigurationService
初始化有一个问题,它是从abstract
类扩展而来的。我完全卡住了
等级划分如下:
public interface ConfigurationService {
TaxPayer getTaxPayer();
}
此类对于需要初始化的服务非常有用:
public abstract class BaseInitializationAwareService {
private boolean initialized = false;
public abstract void initialize();
protected void checkInitialization() {
if (!initialized) {
initialize();
}
}
protected void setInitialized() {
this.initialized = true;
}
}
此类充当配置服务的基类
public abstract class BaseConfigurationService extends BaseInitializationAwareService implements ConfigurationService {
}
对于这个充当配置服务的bean,存在一个问题:
public class DefaultConfigurationService extends BaseConfigurationService {
private TaxPayerService taxPayerService;
@Autowired
public void setTaxPayerService(TaxPayerService taxPayerService) {
Assert.notNull(taxPayerService);
this.taxPayerService = taxPayerService;
}
public void initialize() {
Optional<TaxPayer> dbtaxPayer = taxPayerService.getActiveTaxPayer();
if (!dbtaxPayer.isPresent()) {
throw new IllegalStateException("Tax payer setting not found!");
}
this.taxPayer = dbtaxPayer.get();
setInitialized();
}
// the rest omitted...
}
然后,DefaultConfigurationService
中的taxPayerService
为空-似乎不是自动连接的
它是否可以连接到DefaultConfigurationService
是从抽象类扩展而来的事实?
纳税人服务bean:
@Bean
public TaxPayerService taxPayerService() {
DatabaseTaxPayerService taxPayer = new DatabaseTaxPayerService();
return taxPayer;
}
这个bean可能从未初始化过
这是一个例外:
org.springframework.beans.factory.unsatifiedDependencyException:
创建名为“webSecurityConfig.ApiSecurity”的bean时出错:
通过方法表示的未满足依赖关系
“setContentNegotationStrategy”参数0;嵌套异常是
org.springframework.beans.factory.unsatifiedDependencyException:
创建名为的bean时出错
'org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration':
通过方法“setConfigurers”表示的未满足的依赖关系
参数0;嵌套异常是
org.springframework.beans.factory.unsatifiedDependencyException:
创建名为“passwordRecoverController”的bean时出错:未满足
通过方法“setUserService”参数0表示的依赖关系;
嵌套异常是
org.springframework.beans.factory.unsatifiedDependencyException:
创建名为“defaultUserService”的bean时出错:未满足
通过方法“setNotificationService”参数表示的依赖关系
0; 嵌套异常是
org.springframework.beans.factory.unsatifiedDependencyException:
创建名为“notificationService”的bean时出错:未满足
通过方法“setConfigurationService”表示的依赖关系
参数0;嵌套异常是
org.springframework.beans.factory.BeanCreationException:错误
创建在类路径中定义了名为“configurationService”的bean
resource[com.example.config/AppConfig.class]:通过
工厂方法失败;嵌套异常是
org.springframework.beans.BeanInstantiationException:未能
实例化[com.example.services.BaseConfigurationService]:工厂
方法“configurationService”引发异常;嵌套异常是
java.lang.NullPointerException
例如,需要
BaseConfigurationService
的bean:
public class EmailNotificationService extends BaseService implements NotificationService {
private BaseConfigurationService configurationService;
@Autowired
public void setConfigurationService(BaseConfigurationService configurationService) {
Assert.notNull(configurationService);
this.configurationService = configurationService;
}
// the rest omitted...
}
public class DefaultTransactionDataService implements TransactionDataService {
private PrivateKeyService privateKeyService;
@Autowired
public void setPrivateKeyService(PrivateKeyService privateKeyService) {
Assert.notNull(privateKeyService);
this.privateKeyService = privateKeyService;
}
}
#更新1 与另一个Bean具有内部依赖关系的Bean初始化示例:
@Bean
public TransactionDataService transactionDataService() {
return new DefaultTransactionDataService();
}
和DefaultTransactionDataService
:
public class EmailNotificationService extends BaseService implements NotificationService {
private BaseConfigurationService configurationService;
@Autowired
public void setConfigurationService(BaseConfigurationService configurationService) {
Assert.notNull(configurationService);
this.configurationService = configurationService;
}
// the rest omitted...
}
public class DefaultTransactionDataService implements TransactionDataService {
private PrivateKeyService privateKeyService;
@Autowired
public void setPrivateKeyService(PrivateKeyService privateKeyService) {
Assert.notNull(privateKeyService);
this.privateKeyService = privateKeyService;
}
}
和bean依赖
@Bean
public PrivateKeyService privateKeyService() {
return new DefaultPrivateKeyAwareService();
}
它与Spring如何初始化bean的指令有关: @Bean用于显式声明单个Bean,而不是像上面那样让Spring自动声明。它将bean的声明与类定义分离,并允许您按照自己的选择创建和配置bean 所以,当您手动创建类的实例时,您还必须手动设置所有类字段 可以这样做:
@Bean
public BaseConfigurationService configurationService() {
DefaultConfigurationService configurationService = new DefaultConfigurationService();
configurationService.setTaxPayerService(taxPayerService());
configurationService.initialize();
return configurationService;
}
或者将依赖关系直接移动到构造函数,这样您的DefaultConfigurationService
的依赖关系将更加明显:
@Bean
public BaseConfigurationService configurationService() {
DefaultConfigurationService configurationService = new DefaultConfigurationService(taxPayerService());
configurationService.initialize();
return configurationService;
}
谢谢。关于你的答案,你有更多的信息吗?我不是很确定,因为我描述的问题发生在我创建了抽象类之后。在我的应用程序中,有许多Bean是用
@Bean
注释初始化的,并且具有内部依赖关系。到目前为止,它对我很有效。你可以听从我的建议,也可以不听从。由你决定。我为您提供了更详细描述的链接。您是否有DefaultConfigurationService
注释为@组件
?你什么时候有例外?你在哪里调用你的configurationService()
?@Sergei-也许我们不了解其他人,请阅读我的回答,我写道我有许多Bean是用@Bean
注释初始化的,它们具有内部依赖性,并且这些Bean被正确初始化。请查看我的#1更新版。我理解您的意思,如果使用new
创建类,您可以使用常用的java方法创建它。您了解spring对象创建和平面java对象创建之间的区别吗?@Bean
与XMLBean
声明基本相同。如果您拥有Spring将注入的@Autowired
字段,则不必手动执行任何操作。但是,如果您在spring有时间进行依赖项注入之前调用方法(这里就是这种情况),则不会注入任何内容。问题是您正在从@Bean
方法内部调用initialize
。这将在Spring改变注入依赖项之前被调用。在@Bean
方法中将其指定为initMethod
,而不是自己调用该方法。这将使spring首先创建bean,注入依赖项,然后调用init方法。