小编典典

Autowired属性为null-Spring Boot配置

spring-boot

我在自动装配的属性中陷入空值。我希望可以得到一些帮助。

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

带有bean的四个配置文件在一个软件包中,并按“区域”排序:

  1. 数据源配置
  2. 全局方法安全性配置(因为我们使用Spring-ACL)
  3. MVC配置
  4. 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,但是在使用数据源的firsts 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为null。我们已经尝试通过实现Ordered接口来订购配置文件。我们也尝试使用,@AutoConfigureAfter(RootDataSourceConfig.class)但这也无济于事。除了尝试做之外@AutowiredDataSource我们还尝试注入RootDataSourceConfig类本身,但是它仍然为null。我们尝试在这些bean上使用@DependsOn@Ordered,但再次没有成功。似乎没有任何东西可以注入此配置。

启动时的控制台输出将按我们想要的顺序列出bean,其中数据源是第一个。我们为此受到了很大的阻碍。

我们在这里所做的任何奇怪或独特的事情都不起作用吗?如果这是设计的,那么我们如何才能不同地注入数据​​源?

回购:github


阅读 613

收藏
2020-05-30

共1个答案

小编典典

依赖于a的bean的较早初始化DataSource绝对是问题所在。根本原因与Spring
Boot或自动配置无关,而是通过一个由包裹您的业务bean的方面来应用简单的老式鸡和蛋方法安全性BeanPostProcessor。一个bean只能发表一些初始化处理
非常
早。在这种情况下,进行DataSource注入还为时过早(实际上,实例化@Configuration需要的类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,将其粘贴到并@EnableGlobalMethodSecurity从该类中删除注释。

2020-05-30