Java将对象注册到spring Context中

很多时候需要从spring中取出相应的对象,很多时候又需要将对象注入到spring context中。

小卒碰到了这样的问题。在构件中有DAO. 其他构件需要复用这个DAO,但是连接配置各不相同,并且也有开发测试环境,milestone环境和线上环境的不同分别。需要这个DAO能够获取到其他模块/工程/构件的配置。下面不说废话了,直接上代码:

首先是DAO.java 类。这个类用于load xml等信息构建出context.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
public class DAO {

private static volatile DAO instance = null;

public static DAO getInstance() {
if (instance == null) {
synchronized (DAO.class) {
if (instance == null) {
loadConfiguration();
instance = new DAO();
}
}
}
return instance;
}

private DAO() {

}

private static String configBeanXML = null;
private static Class<?> loadClass = null;

public synchronized static void setConfigBean(String xmlfilePath, Class<?> loadClazz) {
configBeanXML = xmlfilePath;
loadClass = loadClazz;
}

private static ApplicationContext ctx;

public static ApplicationContext getCtx() {
return ctx;
}

private static void loadConfiguration() {
if (configBeanXML != null && loadClass != null) {
LOG.info("load ddb configuration.");
ApplicationContext parent = new ClassPathXmlApplicationContext(new String[]{"raw.xml"}, loadClass);

BeanDefinitionRegistry reg = (BeanDefinitionRegistry)parent.getAutowireCapableBeanFactory();
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(BoneCPDataSource.class);
builder.addPropertyValue("driverClass", "your drive class");


builder.addPropertyValue("jdbcUrl", "your url");

builder.addPropertyValue("username", "username");
builder.addPropertyValue("password", "password");

builder.setDestroyMethodName("close");
reg.registerBeanDefinition("dataSource", builder.getBeanDefinition());
ctx = new ClassPathXmlApplicationContext(new String[]{configBeanXML}, loadClass, parent);
} else {
System.out.println("database configuration can not be load.");
}

}

public JdbcTemplate getJDBCTemplate() {
DataSource datasource = (DataSource) getCtx().getBean("dataSource");
return new JdbcTemplate(datasource);
}

}

这里的逻辑就是首先构造一个空的applicationContext.然后实例化DataSource后,将dataSource注册到applicationCo
ntext中。然后再用这个applicationContext作为父Context构造真正的ApplicationContext.

那个raw.xml就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- keep it empty -->

</beans>

真正用于初始化各个transaction类的xml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

<!-- this is the service object that we want to make transactional -->
<bean id="transA" class="chillyc.info.dao.TransactionA" />



<!-- similarly, don't forget the PlatformTransactionManager -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- the transactional advice (i.e. what 'happens'; see the <aop:advisor/>
bean below) -->
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'get' are read-only -->
<tx:method name="get*" read-only="true" />
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" rollback-for="java.lang.Exception" />
</tx:attributes>
</tx:advice>

<!-- ensure that the above transactional advice runs for any execution of
an operation defined by the Transcation bean interface -->
<aop:config>
<aop:pointcut id="transcationServiceOperation"
expression="execution(* chillyc.info.dao.transactions.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="transcationServiceOperation" />
</aop:config>

<context:component-scan base-package="chillyc.info.dao" />
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="chillyc.info.dao.orm.data" />
</bean>

<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="chillyc.info.dao.orm.mapper" />
</bean>


<!-- other <bean/> definitions here -->

</beans>

这样之后,在初始化database-connection.xml时,各个bean就能获取到dataSource这个对象的引用了。