我在 Autowiring 属性中遇到了空值问题。我希望我能得到一些帮助。
我们正在为项目使用 spring-boot 版本 0.5.0.M6。
四个带有bean的配置文件在一个包中,并按“区域”排序:
- 数据源配置
- 全局方法安全配置(因为我们使用 Spring-ACL)
- MVC 配置
- Spring Security 配置
引导所有内容的主要方法位于以下文件中:
@EnableAspectJAutoProxy
@EnableSpringConfigured
@EnableAutoConfiguration(exclude = {
DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class,
JpaRepositoriesAutoConfiguration.class,
SecurityAutoConfiguration.class,
ThymeleafAutoConfiguration.class,
ErrorMvcAutoConfiguration.class,
MessageSourceAutoConfiguration.class,
WebSocketAutoConfiguration.class
})
@Configuration
@ComponentScan
public class IntegrationsImcApplication {
public static void main(String[] args) throws Exception {
ApplicationContext ctx = SpringApplication.run(
IntegrationsImcApplication.c lass, args);
}
}
保存数据源配置 bean 的第一个文件如下(我省略了一些方法主体部分以使其更具可读性):
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
@Configuration
public class RootDataSourceConfig
extends TomcatDataSourceConfiguration
implements TransactionManagementConfigurer {
@Override
public DataSource dataSource() {
return jpaDataSource();
}
public PlatformTransactionManager annotationDrivenTransactionManager() {
return jpaTransactionManager();
}
@Bean
public HibernateExceptionTranslator hibernateExceptionTranslator() {
return new HibernateExceptionTranslator();
}
@Bean(name="jpaDataSource")
public DataSource jpaDataSource() {......}
@Bean(name = {"transactionManager","txMgr"})
public JpaTransactionManager jpaTransactionManager() {......}
@Bean(name = "entityManagerFactory")
public EntityManagerFactory jpaEmf() {......}
}
这是下一个配置文件,它取决于上面的数据源。它有大约 20 个与 ACL 配置相关的 bean,但在第一个使用数据源的 bean 上失败:
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class RootGlobalMethodSecurityConfig
extends GlobalMethodSecurityConfiguration
implements Ordered {
@Autowired
public DataSource dataSource;
@Override
public int getOrder() {
return IntegrationsImcApplication.ROOT_METHOD_SECURITY_CO NFIG_ORDER;
}
@Bean
public MutableAclService aclService()
throws CacheException, IOException {
MutableJdbcAclService aclService = new MutableJdbcAclService(
dataSource, aclLookupStrategy(), aclCache());
aclService.setClassIdentityQuery("SELECT @@IDENTITY");
aclService.setSidIdentityQuery("SELECT @@IDENTITY");
return aclService;
}
...................................
}
基本上调用aclService()
抛出错误 dataSource
一片空白。我们尝试通过实现 Ordered
来排序配置文件。界面。我们还尝试使用 @AutoConfigureAfter(RootDataSourceConfig.class)
但这也没有帮助。而不是做@Autowired
关于DataSource
我们还尝试注入(inject)RootDataSourceConfig
类本身,但它仍然为空。我们尝试使用 @DependsOn
和@Ordered
在那些 bean 上,但再次没有成功。似乎没有什么可以注入(inject)到这个配置中。
启动时的控制台输出按照我们想要的顺序列出 bean,数据源是第一个。我们几乎被这个阻碍了。
我们在这里做的事情是否有什么奇怪或独特但不起作用的事情?如果这是设计的,那么我们如何以不同的方式注入(inject)数据源?
仓库:github
最佳答案
依赖于DataSource
的bean的急切初始化肯定是问题所在。根本原因与 Spring Boot 或自动配置无关,而是普通的老式先有鸡还是先有蛋的方法安全性是通过由 BeanPostProcessor 包裹在业务 bean 周围的方面来应用的。 bean 只能由非常很早初始化的东西进行后处理。在这种情况下,注入(inject) DataSource
还为时过早(实际上需要 DataSource
的 @Configuration
类被实例化得太早而无法包装正确地在 @Configuration
处理机器中,因此它不能被 Autowiring )。我的建议(这只会让您在缺少 AuthenticationManager
的情况下达到相同的目的)是将 GlobalMethodSecurityConfiguration
声明为嵌套类,而不是 DataSource
需要在:
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
protected static class ActualMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
@Autowired
@Qualifier("aclDaoAuthenticationProvider")
private AuthenticationProvider aclDaoAuthenticationProvider;
@Autowired
@Qualifier("aclAnonymousAuthenticationProvider")
private AnonymousAuthenticationProvider aclAnonymousAuthenticationProvider;
@Autowired
@Qualifier("aclExpressionHandler")
private MethodSecurityExpressionHandler aclExpressionHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth)
throws Exception {
auth.authenticationProvider(aclDaoAuthenticationProvider);
auth.authenticationProvider(aclAnonymousAuthenticationProvider);
}
@Override
public MethodSecurityExpressionHandler createExpressionHandler() {
return aclExpressionHandler;
}
}
即将其保留在 RootMethodSecurityConfiguration
中,并从该类中删除 @EnableGlobalMethodSecurity
注释。
关于java - Autowired 属性为 null - Spring Boot 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20856825/