medkhelifi
medkhelifi

Reputation: 1121

Autowiring xml bean into @Configuration Class

I use generally xml configuration in my Spring project under the three files:

applicationContext.xml: This file contains the main xml configuration: component scan, annotation-config and also an include of two other xml configuration files:

applicationContext-db.xml This file contains all database beans: dataSource, SessionFactory, ...

applicationContext-security.xml This file contains all spring security config.

I need to use also Spring Security ACL, for this I created a configuration 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());
    }
}

My problem is the datasource autowired into Configuration file is null, I don't kwno if i missed something.

My XMLs files are all under: src/main/resources/conf/

There is my datasource bean definition in applicationContext-db.xml

<!--        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>

I already used this bean into Sessionfactory bean defined in the same applicationContext-db.xml file.

PS: When I remove the extended class GlobalMethodSecurityConfiguration my datasource is defined, but I need this org.springframework.security.config.annotation.method.configurationclass to set up my Spring Security ACL configuration.

Upvotes: 1

Views: 979

Answers (2)

medkhelifi
medkhelifi

Reputation: 1121

I found a way to define my datasource bean by using the BeanFactoryAware interface. BeanFactoryAware is used to inject the BeanFactory object. This way we get access to the BeanFactory which created the object.

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

I read that if we use this technic that means we are doing something wrong, I'll continue searching for a proper solution.

Upvotes: 1

Vasif
Vasif

Reputation: 768

Please rename your bean as name="dataSource"

Upvotes: 0

Related Questions