스프링 프레임워크에서 빈을 등록하는 방법으로 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다음과 같이 위의 컴포넌트를 사용하여 동적으로 DataSource 를 추가하여 사용할 수 있다.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); } }
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
댓글 없음:
댓글 쓰기