스프링 프레임워크에서 빈을 등록하는 방법으로 XML 이나 Classpath 검색 기반의 어노테이션을 사용하고 있다. 웹 프로그램에서 설정 정보에 따라 동적으로 Bean을 추가하려면 AutowireCapableBeanFactory 를 사용하면 쉽게 구현이 가능하다.
예를 들어 데이터베이스 접속을 위한 DataSource 를 동적으로 추가한다고 해보자 .
package tests;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.support.DatabaseMetaDataCallback;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.stereotype.Component;
@Component
public class SetupService implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(SetupService.class);
private ApplicationContext applicationContext = null;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public SetupService() {
}
public boolean testConnection(DataSource dataSource) {
try {
JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
logger.debug( "Database Connection Test : {}" , true );
logger.debug( "Database Product Name : {}" , dbmd.getDatabaseProductName() );
logger.debug( "Database Product Version : {} " , dbmd.getDatabaseProductVersion() );
logger.debug( "JDBC DriverName : {} " , dbmd.getDriverName() );
logger.debug( "JDBC Driver Version : {} " , dbmd.getDriverVersion());
return dbmd;
}
});
return true;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return false;
}
public T getComponent(String requiredName, Class requiredClass) {
return applicationContext.getBean(requiredName, requiredClass);
}
public void registerDataSourceBean(String name, Properties connectionProperties) {
AutowireCapableBeanFactory factory = applicationContext.getAutowireCapableBeanFactory();
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) factory;
if(registry.containsBeanDefinition(name)) {
registry.removeBeanDefinition(name);
}
GenericBeanDefinition myBeanDefinition = new GenericBeanDefinition();
MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
mutablePropertyValues.add("url", connectionProperties.getProperty("url"));
mutablePropertyValues.add("username", connectionProperties.getProperty("username"));
mutablePropertyValues.add("password", connectionProperties.getProperty("password"));
mutablePropertyValues.add("connectionProperties", connectionProperties);
myBeanDefinition.setBeanClass(DriverManagerDataSource.class);
myBeanDefinition.setPropertyValues(mutablePropertyValues);
registry.registerBeanDefinition(name, myBeanDefinition);
}
}
다음과 같이 위의 컴포넌트를 사용하여 동적으로 DataSource 를 추가하여 사용할 수 있다.
Properties connectionProperties = new Properties();
connectionProperties.setProperty("DriverClassName", "oracle.jdbc.OracleDriver");
connectionProperties.setProperty("url", "jdbc:oracle:thin:@//localhost:1521/orcl");
connectionProperties.setProperty("username", "**" );
connectionProperties.setProperty("password", "**");
setupService.registerDataSourceBean("dataSource", connectionProperties);
DataSource dataSource = setupService.getComponent("dataSource", DataSource.class);
setupService.testConnection(dataSource);
환경
Java : 1.8.xSpringframework : 4.3.23.RELEASE
댓글 없음:
댓글 쓰기