这篇是承接《轻量级 Java 开发框架 设计》系列Blog文的后续文章,本文将介绍 Hasor 内部主要插件并附带插件的功能描述和简单使用 Demo。
Hasor 使用的是“微内核 + 插件扩展”这种设计思想。截止到目前为止 Hasor-Core、Hasor-Web、Hasor-JDBC 中一同提供了 14 个功能插件。本文收集并整理了 Hasor-Core、Hasor-Web 两个部分中 11个插件的功能说明以及基本 Demo。
这 14 个功能模块分别在开发的各个方面给予开发人员各种便捷。假如你不想要其中的某个模块可以将其禁用掉。这比起 Spring 而言不管有用没用都引一大堆功能而言要更加贴切,如果你不喜欢这些功能模块大可以放弃它们仅仅启动 Hasor 的内核。这样你会得到更轻量的框架,因为 Hasor 的核心实现仅有不到 50 个类文件。
这里是一个基于 Hasor 的 WebDemo 工程,工程中还实现了一个 Hessian 插件。地址:http://git.oschina.net/zycgit/hasor/tree/master/examples/SimpleWeb
Hasor-Core 软件包
Aop 插件
通过 @Aop、@GlobalAop 两个注解提供声明 Aop 切面。@Aop 可以标记到方法或类上,根据标记的位置来决定 Aop 切面作用的范围。@GlobalAop 注解
是标记到拦截器上的,用于配置全局拦截器,拦截范围可以通过注解进行配置。
支持表达式配置;支持 Aop 链。 例子:
@Before(AopInterceptor_2.class)//类级别拦截器
public class TestBean {
@Before(AopInterceptor_1.class)//方法级别拦截器
public String println(String msg) { //受到方法级、类级拦截器影响的方法
return "println->" + msg;
}
public String foo(String msg) { //只受到类级拦截影响的方法
return "foo->" + msg;
}
}
Bean 插件
该插件会将所有标记了 @Bean 的类通过“ApiBinder.defineBean(...)”
代码将其注册到 Hasor 容器中。注册之后可以通过“AppContext.getBean”
获取Bean对象。用过 Spring 的话一定不会陌生。例子:
@Bean(value = { "name1", "name2" })
public class NamesBean {
public void foo() {
System.out.println("this bean is name1 or name2 type:" + this);
}
}
Cache 插件
该插件本身并不提供缓存功能,但是为使用缓存提供了统一的接口。缓存功能
的提供需要实现 CacheCreator 接口并通过标记 @Creator 注解以生效。
使用缓存可以通过在需要缓存的方法上通过标记 @NeedCache 注解以启用结果缓存。例子:
@NeedCache
public MenuBean findMenuByCode(String code) {
return ...;
}
@Creator
public class MapCacheCreator implements CacheCreator {
private Map<String, Cache> cacheMap = new HashMap<String, Cache>();
public Cache getCacheByName(AppContext appContext, String groupName) {
Cache cache = cacheMap.get(groupName);
if (cache != null)
return cache;
cache = new MapCache();
cacheMap.put(groupName, cache);
return cache;
}
}
public class MapCache extends HashMap<Serializable, Object> implements Cache {
public boolean toCache(Serializable key, Object value) {
this.put(key, value);
return true;
}
public Object fromCache(Serializable key) {
return this.get(key);
}
public boolean hasCache(Serializable key) {
return this.containsKey(key);
}
public boolean remove(Serializable key) {
super.remove(key);
return true;
}
public boolean clearCache() {
super.clear();
return true;
}
public int size() {
return super.size();
}
public Set<Serializable> keys() {
return super.keySet();
}
public void close() {
super.clear();
}
}
Event 插件
通过标记 @Listener 注解声明一个 “net.hasor.core.EventListener”类型的事件监听器。通过“EventManager.doSync or .doAsync”可以引发事件。
Hasor 中事件的处理分为同步(Sync)和异步(Async)。例子:
AppContext appContext = ...;
/*发送异步事件*/
appContext.getEventManager().doAsyn("EventName", ...);
AppContext appContext = ...;
/*发送同步事件*/
appContext.getEventManager().doSync("EventName", ...);
@Listener("EventName")
public class Type_B_EventListener implements EventListener {
public void onEvent(String event, Object[] params) {
System.out.println("Type_B onEvent :" + event + " \t" + Hasor.logString(params));
Thread.sleep(1000);
}
};
Guice 插件
通过 @GuiceModule 注解可以将任意一个基于 Guice 开发的“com.google.inject.Module”
模块加入到 Hasor 中作为 Hasor 的一个模块。例子:
@GuiceModule
public class GuiceMod implements Module {
public void configure(Binder binder) {
System.out.println("Hello guice");
}
}
Setting 插件
通过 @Settings 注解声明一个配置文件改变监听器。Hasor 在启动之后会持续监听配置文件是否改变,如发生改变 Hasor 会自动重载它。标记了 @Settings 注解的
SettingsListener监听器会收到这个通知。例子:
(未整理...)
Hasor-Web 软件包
Controller 插件
通过 @Controller 注解提供了 WebMVC 开发所需的支持。该插件还提供了请求响应拦截器功能。
所有控制器都必须要求继承自 AbstractController 抽象类,如果某个方法不像被发布成 action,
可以通过@ControllerIgnore 注解或者配置“hasor-web.controller.globalIgnore”隐藏它们。例子:
@Controller("/mgr/user")
public class UserAction extends AbstractController {
@Inject
private UserService userService;
/*获取用户列表,转发到‘/mgr/user/userList.jsp’*/
@Forword
public String userList() {
List<UserBean> userList = userService.getUserList();
this.setAttr("userList", userList);
return "/mgr/user/userList_mvc1.jsp";
}
}
请求地址为:http://127.0.0.1:8080/mgr/user/userList.do
Restful 插件
通过 @RestfulService 注解发布 Restful 服务的支持,Hasor 的 restful 参考了 JSR-311。
@Any、@AttributeParam、@CookieParam、@Get、@Head、@HeaderParam、@HttpMethod、@Options、@Path、@PathParam、@Post、@Produces、@Put、@QueryParam 这些注解是由这个插件提供的。例子:
@RestfulService
public class MenusRestFul {
@Inject
private MenuServices menuServices;
/*使用重定向转发*/
@Redirect
/*映射 restful 服务地址,并定义一个参数*/
@Path("/mgr/menus/nav/{menuCode}")
/*取得并参数,并跳转到对应的页面*/
public String menuList(@PathParam("menuCode") String menuCode) {
MenuBean menuBean = menuServices.findMenuByCode(menuCode);
return (menuBean == null) ? "/mgr" : menuBean.getUrl();
}
}
请求地址为:http://127.0.0.1:8080/mgr/menus/nav/<code>
Result 插件
该插件是 Controller、Result两个插件的扩展插件,它为上述两个插件提供了返回值集处理机制。
@Forword、@Include、@Json、@Redirect 就是它提供的,开发者还可以自己另外自定义扩展。例子:
@Controller("/action")
public class SimpleAction extends AbstractController {
@Json
public Map<String, Object> json() {
HashMap<String, Object> returnData = new HashMap<String, Object>();
returnData.put("data1", true);
returnData.put("data2", 123); return returnData;
}
//
@Forword
public String forwordTo() {
return "/index.htm";
}
@Redirect
public String redirectTo() {
return "http://www.baidu.com";
}
}
Servlet3 插件
该插件是用来支持Servlet3.0 规范的软件包,当 Servlet 容器不支持 Servlet3.0 规范时可以
通过该插件提供的 @WebFilter、@WebServlet、@WebInitParam 来实现 Servlet3.0。例子:
@WebFilter("/*")
public class TestFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("before Servlet. from " + request.getRequestURI());
chain.doFilter(request, response);
System.out.println("after Servlet. from " + request.getRequestURI());
}
public void destroy() {}
}
@WebServlet("showname.c")
public class HelloWordServlet extends HttpServlet {
@Inject
private AppContext appContext = null;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
CustomerBean infoBean = this.appContext.getInstance(CustomerBean.class);
infoBean.foo();
//
resp.getWriter().write("Call Servlet showname.c");
super.service(req, resp);
}
}
Resource 插件
通过这个插件可以将位于ClassPath、Zip等位置中的资源用作 Web 请求响应。插件是以
Servlet 方式提供,开发者需要自己注册它。例子:
@Plugin
public class CustomResources extends AbstractWebHasorPlugin {
public void loadPlugin(WebApiBinder apiBinder) {
//
//js,css,gif,ico,jpg,jpeg,png,swf,swc,flv,mp3,wav,avi
apiBinder.serve("*.js").with(ResourceHttpServlet.class);
apiBinder.serve("*.css").with(ResourceHttpServlet.class);
apiBinder.serve("*.wav").with(ResourceHttpServlet.class);
apiBinder.serve("*.avi").with(ResourceHttpServlet.class);
//
apiBinder.getGuiceBinder().bind(ResourceLoaderFactory.class).toInstance(new ResourceLoaderFactory() {
public ResourceLoader[] loaderArray(AppContext appContext) {
ResourceLoader classLoader = new ClassPathResourceLoader("/META-INF/webapp");
return new ResourceLoader[] { classLoader };
}
});
}
}
Hasor-JDBC 软件包
JDBC 的使用参考:http://my.oschina.net/u/1166271/blog/186940
来源:oschina
链接:https://my.oschina.net/u/1166271/blog/191847