我在自动装配属性中遇到空值。我希望能得到一些帮助。
我们正在使用项目spring-boot版本0.5.0.M6。
带有bean的四个配置文件位于一个包中,并按“area”排序:
引导所有内容的主要方法在以下文件中:
@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
,而是尝试注入RootDataSourceConfig
类本身,但它仍然为空。我们尝试在这些bean上使用@DependsOn
和@Ordered
但是再次没有成功。似乎没有任何东西可以注入这种配置。
启动时的控制台输出是按照我们想要的顺序列出bean,数据源是第一个。我们几乎被这个阻止了。
我们在这里做的任何奇怪或独特的东西都不起作用吗?如果这是设计的,那么我们如何以不同的方式注入数据源呢?
回购:github
答案 0 :(得分:4)
依赖于DataSource
的bean的急切初始化肯定是个问题。根本原因与Spring Boot或自动配置无关,而是简单的老式鸡和蛋 - 方法安全性通过BeanPostProcessor
围绕您的业务bean的方面应用。 bean只能通过早期非常初始化的内容进行后期处理。在这种情况下,注入DataSource
为时尚早(实际上需要@Configuration
的{{1}}类过早实例化,无法在DataSource
处理机器中正确包装,所以它不能自动装配)。我的提案(只能让您与缺少的@Configuration
达到同一点)是将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
注释。
答案 1 :(得分:0)
我可能已经解决了这个问题。
GlobalMethodSecurityConfiguration.class
具有以下设置器,尝试自动装配权限评估程序:
@Autowired(required = false)
public void setPermissionEvaluator(List<PermissionEvaluator> permissionEvaluators) {
....
}
在我的情况下,aclPermissionEvaluator()
bean需要aclService()
bean,而bean又依赖于另一个自动装配的属性:dataSource
。这似乎还没有自动装配。
要解决此问题,我实施了BeanFactoryAware
并从dataSource
获取了beanFactory
:
public class RootMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration implements BeanFactoryAware {
private DataSource dataSource;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.dataSource = beanFactory.getBean("dataSource", DataSource.class);
}
....
}
此后,出现了其他异常,其中SecurityAutoConfiguration.class
抱怨缺少AuthenticationManager,所以我只是将其从@EnableAutoConfiguration
中排除。我不确定它是否理想,但我有自定义安全配置,所以这样一切正常。