自动连接属性为null - Spring引导配置 [英] Autowired property is null - Spring Boot Configuration

查看:758
本文介绍了自动连接属性为null - Spring引导配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个自动连接属性中的空值。我希望我能得到一些帮助。

I am stuck with null values in an autowired property. I am hoping I could get some help.

我们正在使用的项目spring-boot版本0.5.0.M6。

We are using for the project spring-boot version 0.5.0.M6.

这四个包含bean的配置文件在一个包中并按area排序:
1.数据源配置
2.全局方法安全配置(因为我们使用Spring-ACL)
3 MVC配置
4. Spring Security配置

The four configuration files with beans are in one package and are sorted by "area": 1. Data source configuration 2. Global method security configuration (as we use Spring-ACL) 3 MVC configuration 4. Spring Security configuration

引导一切的主要方法在以下文件中:

The main method that bootstraps everything is in the following file:

@EnableAspectJAutoProxy
@EnableSpringConfigured
@EnableAutoConfiguration(exclude = {
    DataSourceTransactionManagerAutoConfiguration.clas s,
    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的第一个文件是如下(我已经省略了一些方法主体部分,使其更易读):

The first file that holds the data source configuration beans is as follows (I have omitted some method body parts to make it more readable):

@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上失败:

And here is the next configuration file, that depends on the data source from above. It has about 20 beans related to ACL configuration, but it fails on the firsts bean that uses data source:

@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;
    }

    ...................................

}

基本上,由于dataSource为null,所以调用aclService()会抛出一个错误。我们尝试通过实现Orderered接口来排序配置文件。我们也尝试使用@AutoConfigureAfter(RootDataSourceConfig.class),但这也没有帮助。而不是在DataSource上执行@Autowired,我们还尝试注入RootDataSourceConfig类itselft,但它仍然为null。我们尝试在这些bean上使用@DependsOn和@Ordered,但是没有成功。看起来没有什么可以注入到这个配置。

Basically invoking aclService() throws an error as dataSource is null. We have tried ordering the configuration files by implementing the Ordered interface. We also tried using @AutoConfigureAfter(RootDataSourceConfig.class) but this did not helped either. Instead of doing @Autowired on the DataSource we also tried injecting the RootDataSourceConfig class itselft, but it was still null. We tried using @DependsOn and @Ordered on those beans but again no success. It seems like nothing can be injected to this configuration.

启动时的控制台输出列出了我们想要的bean,数据源是第一个。我们几乎被这个阻挡了

The console output at the startup is listing the beans in order we want them, with data source being the first. We are pretty much blocked by this

有没有什么奇怪或独特我们在这里做,它不工作?如果这是按照设计,那么我们如何以不同的方式注入数据源呢?

Is there anything weird or unique we are doing here that it is not working? If this is as designed, then how could we inject data source there differently?

Repo: github

尊敬的,
Dominika

Regards, Dominika

推荐答案

依赖于 DataSource 的bean的初始化肯定是问题。根本原因与Spring Boot或自动配置无关,而是普通的老式鸡和蛋 - 方法安全性通过一个方面应用,该方面由一个 BeanPostProcessor $ c>。一个bean只能由早期初始化的东西进行后处理。在这种情况下,注入 DataSource (实际上是 @Configuration 类需要 DataSource 实例化太早,无法在 @Configuration 处理机器中正确包装,因此不能自动装配)。我的建议(只让你缺少 AuthenticationManager 的同一点)是将 GlobalMethodSecurityConfiguration 声明为嵌套类而不是 DataSource 所需的类:

Eager initialization of a bean that depends on a DataSource is definitely the problem. The root cause is nothing to do with Spring Boot or autoconfiguration, but rather plain old-fashioned chicken and egg - method security is applied via an aspect which is wrapped around your business beans by a BeanPostProcessor. A bean can only be post processed by something that is initialized very early. In this case it is too early to have the DataSource injected (actually the @Configuration class that needs the DataSource is instantiated too early to be wrapped properly in the @Configuration processing machinery, so it cannot be autowired). My proposal (which only gets you to the same point with the missing AuthenticationManager) is to declare the GlobalMethodSecurityConfiguration as a nested class instead of the one that the DataSource is needed in:

@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 注释。

这篇关于自动连接属性为null - Spring引导配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆