Bind介绍
Hasor-Core 在0.0.8版本开始内置了 Bind 机制,这个机制是在 Guice 思想上发展而来。目前最新版本是 2.4.5。这一套 Bind 机制已经发展成熟。
创建Hasor AppContext 对象:
如果您对Hasor没有什么特殊的要求可以使用下面这样一行简单的代码创建 AppContext 对象。
AppContext appContext = Hasor.createAppContext(new Module() {
public void loadModule(ApiBinder apiBinder) throws Throwable {
......
}
});
声明一个接口和其实现类,然后通过AppContext获取接口实例:
public interface PojoInfo {
public String getName();
public String getAddress();
}
public class PojoBean implements PojoInfo {
private String uuid = UUID.randomUUID().toString();
private String name = "马三";
private String address = "北京马连洼街道办...";
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
System.out.println("--->>faceBindTest<<--");
//1.创建一个标准的 Hasor 容器。
AppContext appContext = Hasor.createAppContext(new Module() {
public void loadModule(ApiBinder apiBinder) throws Throwable {
//绑定一个接口和实现类
apiBinder.bindType(PojoInfo.class).to(PojoBean.class);
}
});
//
//通过接口获取绑定的Bean
PojoInfo myBean2 = appContext.getInstance(PojoInfo.class);
System.out.println(myBean2.getName() + "\t" + myBean2);
带有名字的 Bind:
前面例子已经高速我们您可以通过在Hasor上声明一个接口然后为这个接口绑定了一个实现类。下面这个例子考虑到当一个接口有多个实现类的时候 Hasor 如何处理它们的绑定以及获取。下面这个例子是为 CharSequence 接口指定了两个不同的实现(String 类实现了 CharSequence 接口)。
System.out.println("--->>nameBindTest<<--");
//1.创建一个标准的 Hasor 容器。
AppContext appContext = Hasor.createAppContext(new Module() {
public void loadModule(ApiBinder apiBinder) throws Throwable {
//绑定一个接口和实现类
apiBinder.bindType(CharSequence.class).nameWith("ModuleA").toInstance("this String form A");
apiBinder.bindType(CharSequence.class).nameWith("ModuleB").toInstance("this String form B");
}
});
//
System.out.println();
CharSequence modeSay = null;
modeSay = appContext.findBindingBean("ModuleA", CharSequence.class);
Hasor.logInfo(modeSay.toString());
modeSay = appContext.findBindingBean("ModuleB", CharSequence.class);
Hasor.logInfo(modeSay.toString());
基于上面这个例子,我现在想知道 CharSequence 接口都绑定了哪些实现?
//查找所有绑定
List<CharSequence> says = appContext.findBindingBean(CharSequence.class);
Hasor.logInfo("say %s.", says);
Bind机制有何用?
我想随意造出一个自认为牛逼的功能本身并不是什么有价值的事情,关键问题是造出的东西会带给我们什么?下面就看一些实际的应用场景:
A。多数据源
在Hasor中我们可以为多个数据库指定不同的数据库连接池,让数据库连接转化为 DataSource 接口对象。然后在为不同的数据源 指定名称,绑定其特定的连接池对象。最后在程序中就可以通过不同的名称去访问你需要的数据库。
DataSource ds1= appContext.findBindingBean("my1", DataSource.class);
DataSource ds2= appContext.findBindingBean("my2", DataSource.class);
B。不同用户身份的认证
我遇到一个系统,这个系统中包含了“老师”、“学生”、“家长”三个不同的身份。但是由于数据来源不同我不能用一张统一的表去装载这三类用户数据,所以只能将三个不同的用户张表看作三张不同的表。然后我设计了一个接口 AuthFace 在这个接口中用一个方法用来测试用户是否具备这个身份。无论那类用户身份认证都只需要实现这个接口就可以了。
Hasor 的接口绑定机制恰好可以帮助你管理这些 AuthFace 实现。
高级一点的玩法!
下面就展示一下 Bind 这种机制的一个高级一点的玩法,用它来开发一个简单的Web MVC 框架。首先我们假定所有标记 @Action的类都是Action,而且每个Action 都需要实现一个接口,下面是定义:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Action {
public String value();
}
public interface ActionFace {
public void execute(HttpServletRequest request, HttpServletResponse response);
}
作为一个正确的Action应该是如下样子的。
@Action("/hello.do")
public class FirstAction implements ActionFace{
public void execute(HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
}
}
接下来向大家展示如何将Action注册到 Hasor 上
//1.创建一个标准的 Hasor 容器。
AppContext appContext = Hasor.createAppContext(new Module() {
public void loadModule(ApiBinder apiBinder) throws Throwable {
//1.找到Action
Set<Class<?>> actions = apiBinder.findClass(ActionFace.class);
//2.是否标记@Action
for (Class<?> type : actions) {
Action actAnno = type.getAnnotation(Action.class);
if (actAnno == null)
continue;
//3.绑定一个接口的实现类
String actionPath = actAnno.value();
Class<ActionFace> actType = (Class<ActionFace>) type;
apiBinder.bindType(ActionFace.class).nameWith(actionPath).to(actType);
}
}
});
接下来需要写一个Servlet拦截所有“.do”结尾的请求,并且找到需要派发的控制器,调用它。
class ActionIn extends HttpServlet {
private AppContext appContext = null;
public void init() throws ServletException {
//1.创建一个标准的 Hasor 容器。
this.appContext = Hasor.createAppContext(new LoadActionModule());
}
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String actionPath = req.getRequestURI().substring(req.getContextPath().length());
ActionFace action =this.appContext.findBindingBean(actionPath, ActionFace.class);
if (action!=null)
action.execute(req, resp);
else
resp.sendError(404);
}
}