java - Autowired 属性为 null - Spring Boot 配置

标签 java spring-boot configuration nullpointerexception autowired

我在 Autowiring 属性中遇到了空值问题。我希望我能得到一些帮助。

我们正在为项目使用 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,但在第一个使用数据源的 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/

相关文章:

c++ - Visual Studio 2008 : Use external Debug-DLL for Debug-Run and external Release-DLL for Release-Run

java - HashMap值的计算

xml - InelliJ和apache tomcat8在.IntelliJIdea15/system/tomcat/Unnamed_Form/conf目录下发现没有server.xml

java - IntelliJ IDEA Gradle 与 Maven "Run all tests"通过右键单击 `sources-root` 与 `test-sources-root` 文件夹?

java - 如何使用ribbon客户端修复没有可用于微服务的实例

spring-boot - Jackson - 通过 Jackson2ObjectMapperBuilderCustomizer 配置集合覆盖

spring-boot - 如何使 Swagger 3 UI 以 DDMMYYYY 格式显示示例日期?

java - 应用程序崩溃时编辑对话框

java - 如何创建一个只有一个变量的对象,该变量可以是两种数据类型之一?

java - 单例类的 hashCode 实现