将 xml bean 自动装配到 @Configuration Class

Autowiring xml bean into @Configuration Class

我在我的Spring项目下一般使用xml配置三个文件:

applicationContext.xml: 此文件包含主要的 xml 配置:组件扫描、注释配置以及另外两个 xml 配置文件的包含:

applicationContext-db.xml 此文件包含所有数据库 bean:dataSource、SessionFactory、...

applicationContext-security.xml 此文件包含所有 spring 安全配置。

我还需要使用 Spring 安全 ACL,为此我创建了一个配置 class:

AclMethodSecurityConfiguration.java

package com.medkhelifi.tutorials.todolist.conf;

/**
/* all imports goes here.
**/

@Configuration
@ImportResource({"classpath*:conf/applicationContext-db.xml"})
@EnableGlobalMethodSecurity (prePostEnabled = true, securedEnabled = true)
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {

    @Autowired
    DataSource dataSource;

    @Bean
    public MethodSecurityExpressionHandler defaultMethodSecurityExpressionHandler() {
        DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
        AclPermissionEvaluator permissionEvaluator = new AclPermissionEvaluator(aclService());
        expressionHandler.setPermissionEvaluator(permissionEvaluator);
        return expressionHandler;
    }


    @Bean
    public JdbcMutableAclService aclService() {
        return new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
    }

    @Bean
    public AclAuthorizationStrategy aclAuthorizationStrategy() {
        return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ADMIN"));
    }


    @Bean
    public PermissionGrantingStrategy permissionGrantingStrategy() {
        return new DefaultPermissionGrantingStrategy(new ConsoleAuditLogger());
    }


    @Bean
    public EhCacheBasedAclCache aclCache() {
        return new EhCacheBasedAclCache(
                    aclEhCacheFactoryBean().getObject(),
                    permissionGrantingStrategy(),
                    aclAuthorizationStrategy()
                    );
    }

    @Bean
    public EhCacheFactoryBean aclEhCacheFactoryBean() {
        EhCacheFactoryBean ehCacheFactoryBean = new EhCacheFactoryBean();
        ehCacheFactoryBean.setCacheManager(aclCacheManager().getObject());
        ehCacheFactoryBean.setCacheName("aclCache");
        return ehCacheFactoryBean;
    }

    @Bean
    public EhCacheManagerFactoryBean aclCacheManager() {
        return new EhCacheManagerFactoryBean();
    }

    @Bean
    public LookupStrategy lookupStrategy() {
        return new BasicLookupStrategy(
                    dataSource,
                    aclCache(),
                    aclAuthorizationStrategy(),
                    new ConsoleAuditLogger());
    }
}

我的问题是自动连接到配置文件的数据源为空,我不知道是否遗漏了什么。

我的 XML 文件都在:src/main/resources/conf/

applicationContext-db.xml

中有我的数据源bean定义
<!--        DATASOURCE                      -->
<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${database.driver}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.username}"/>
    <property name="password" value="${database.password}"/>
</bean>

我已经将这个 bean 用于同一 applicationContext-db.xml 文件中定义的 Sessionfactory bean。

PS:当我删除扩展 class GlobalMethodSecurityConfiguration 时,我的数据源已定义,但我需要这个 org.springframework.security.config.annotation.method.configurationclass设置我的 Spring 安全 ACL 配置。

请将您的 bean 重命名为 name="dataSource"

我找到了一种使用 BeanFactoryAware 接口定义数据源 bean 的方法。 BeanFactoryAware 用于注入 BeanFactory 对象。这样我们就可以访问创建对象的 BeanFactory。

@EnableGlobalMethodSecurity (prePostEnabled = true, securedEnabled = true)
@Configuration
@ImportResource({"classpath:/conf/applicationContext-db.xml"})
public class AclMethodSecurityConfiguration extends GlobalMethodSecurityConfiguration implements BeanFactoryAware {

    DataSource dataSource;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.dataSource = beanFactory.getBean("dataSource", DataSource.class);
    }
    // rest of code goes here 
}

我读到如果我们使用这个技术就意味着我们做错了什么,我会继续寻找合适的解决方案。