额 标题 "guice使用初探:取代工厂模式返回单例 " 似乎取得不太对 这边要取代的是利用工厂模式返回 单例(好像说法没变吗喂....)
分类还是放在编程语言里了..话说企业架构里用guice本菜鸟真的没见过啊(本菜鸟除了SSH SSM 好像没见过其他的了 跪Orz..)
好了 废话说到这(下面也许还会有..)
需要的jar包:
guice下载地址:
https://code.google.com/p/google-guice/
这里使用guice的DI(依赖注入)完成IoC(控制反转) 将数据库相关对象注入给DAO的属性(Field)
要注入的类是:
ConnectionUtil
注入的DAO是:
AccountDao
步奏:
首先建立一个类继承Guice的相关抽象类 来充当注入的提供者:
代码1:
package org.cc.mongo.infrustructure.di;
import java.net.UnknownHostException;
import javax.inject.Singleton;
import org.cc.mongo.infrustructure.ConnectionUtil;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
public class ConnectionUtilModule extends AbstractModule {
@Override
protected void configure() {
// 这里可以写绑定关系 将接口与实现类绑定 注入给接口绑定的实现类使用bind(实现类).to(接口)
}
@Provides //提供者标记
@Singleton //表示是单例 util只会被初始化一次
ConnectionUtil provideAgentFinder() //返回注入器需要的类型
{
/**创建util并返回具体值*/
ConnectionUtil util = new ConnectionUtil();
try {
util.configure().connect();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return util;
}
}
接下去在AccountDao中注入:
代码2:
public class AccountDao extends BaseDao {
public static final String COLLECTION_NAME="account";
private ConnectionUtil conn;
private DBCollection collection;
@Inject
public AccountDao(ConnectionUtil conn) throws UnknownHostException {
super();
this.conn=conn;
this.collection=conn.getCollection(COLLECTION_NAME);
}
... ...
}
然后测试是这样的:
代码3:
@Test
public void test() {
Injector injector = Guice.createInjector(new ConnectionUtilModule());
AccountDao ad = injector
.getInstance(AccountDao.class);
Account acc = new Account();
acc.setName("x15");
acc.setInfo("empty");
acc.setPassword("23456");
ad.add(acc);
AccountDao ad2 = injector
.getInstance(AccountDao.class); //检查ConnectionUtil对象是否是单例
acc.setName("x16");
acc.setInfo("empty");
acc.setPassword("23456");
ad2.add(acc);
}
然后运行这个测试 查看结果:
2013-08-15 00:24:38:560 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - mongo初始化成功..
2013-08-15 00:24:38:567 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
2013-08-15 00:24:38:567 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
可见只connect()了一次 (每进行一次连接就会输出一次)
为了再看得清楚一点 把代码1中的@Singleton标记去除 再运行一次测试(以上的数据也要做调整 因为我在name里建了一个唯一索引 不然会出错):
2013-08-15 00:56:37:341 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - mongo初始化成功..
2013-08-15 00:56:37:347 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
2013-08-15 00:56:37:416 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - mongo初始化成功..
2013-08-15 00:56:37:416 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
2013-08-15 00:56:37:347 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
2013-08-15 00:56:37:416 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - mongo初始化成功..
2013-08-15 00:56:37:416 INFO [main] org.cc.mongo.infrustructure.ConnectionUtil - Connect()成功
发现连接了两次 说明前面的的确是单例
这里总结一下一些使用到的annotation(JSR-330):
- @Inject:和@Resource用处相近 注入对象使用 可以用在构造方法 setter以及属性上
- @Provides:AbstractModule中使用(可以写多个 还可以不用这个注解 实现Provider接口) 表示提供者
- @Singleton:和@Provides一起使用表示提供者提供的是单例
这只是guice的简单使用 更多使用各位有需求的话可以自己去找一找^_^