您的位置:首页 > 其它

【step by step构建轻量级web框架】轻量级框架jbeer预览

2014-06-17 23:18 435 查看
本系列博文,将会一步一步介绍如何构建一个轻量级的web框架jbeer git地址:http://git.oschina.net/bieber/jbeer

经过本人差不多半年的纠结,今天终于把JBeer的0.1版本完成了。Jbeer具备MVC,IOC,AOP,ORM,IN18,PropertiesContext,简单声明式事务以及自带Datasource功能。开发Jbeer的目的是为了总结J2EE框架原理,从而在一些细节上加入一些自己的想法,最终目的是个人的一个总结。当初第一次看到JFinal源码的时候,知道了MVC框架内部的原理原来是那样的,第一次参与了Smart4j(原来smart),了解了轻量级的框架是那样子的。于是便萌发了自己也做一个这样的东西来总结一下。JBeer并不是站在代替JFinal,smart4j或者ssh框架去实现的,而是一次总结的过程。之前只是站在框架的外围看它,当你站到框架内部去看它的时候,你会发现你才真正的理解了它。废话不多说,先出一个JBEER的“一寸免冠照片”来给大家瞅瞅



看了JBeer的仪容之后,那么下面大概介绍一下各个功能吧。

在介绍各个功能之前,还是先废话一下。JBEER是追求极少的配置文件,这是借鉴了JFinal的风格。需要使用JBEER,只需要将项目依赖jbeer的jar包,然后在web.xml中配置如下信息即可

<context-param>
<param-name>basePackageName</param-name>
<param-value>org.jbeer.sample</param-value>
</context-param>
<listener>
<listener-class>com.jbeer.framework.startup.JBeerWebContextListener</listener-class>
</listener>
<servlet>
<servlet-name>jbeerDispatcherServlet</servlet-name>
<servlet-class>com.jbeer.framework.web.JBeerDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>jbeerDispatcherServlet</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>

然后实现一个Configurate接口,需要注意的是,实现Configurate接口的类必须在上面web.xml里面配置的basePackageName的包内或者子包内。下面给出了一个实例:
public class AppConfig implements Configurate {
public void configurateContext(JBeerConfig config) {
config.setApplicationEncode("UTF-8");
}
public void configurateAop(AopConfig config) {
}
public void configurateDB(DBConfig config) {

}
public void configurateWeb(WebConfig config) {
config.setViewPrefix("/WEB-INF/pages");
config.setViewSuffix(".jsp");
}
public void configureateIOC(IOCConfig config) {
}
public void configurateIN18(IN18Config config) {
config.setBaseName("in18_message");
}
public void configurateProperties(PropertiesConfig config) {
config.setPropertiesPath("*_test.properties");
config.setPropertiesPath("conf/*.properties");
}
}

这样,你的项目就可以使用jbeer来进行开发了。
一、MVC模块
该模块借鉴了Spring mvc的风格,采用注解的方式来配置请求与处理action的关系。实例如下:
@Controller(urlPattern="/first")
public class FirstController {
private User user;
@Action(urlPatterns="index.htm",requestType=RequestType.ANY)
public ModelAndView index() throws IOException, ScanClassException{
PageModelAndView mav = ModelAndView.createModelAndView();
mav.setDataMap("user", userService.getName());
mav.setView("view");
return mav;
}
public void setUser(User user) {
this.user = user;
}
}

上面就完成了一个简单的controller和action,当访问/first/index.htm的时候,则会触发index方法执行,然后返回视图和数据模型。上面有一个User字段,字段名是user,并且有setUser方法,当请求参数中包含user.name字段传递过来,则会自动封装成User对象的name字段,并且调用setUser方法复制给当前的controller。在Action注解的urlPatterns支持restful风格的请求路径,比如index_${id}_${name}.html,并且在对应的action的方法入参(@PathParam(“id”)int id, @PathParam(“name”)String name),这样当请求的时候将会自动将路径对应的占位符内容当作入参传入。具体细节,后面会在每个单独模块总介绍。
二、IOC模块
IOC通过Bean注解申明是一个IOC的bean实体,通过RefBean表明应用IOC容器中的一个实体。不多说,直接粘贴处实例代码。
@Bean
public class UserService {
@RefBean
private CodeService codeService;
public String getName(){
return codeService.hello()+" world";
}
}
RefBean注解是可以定义在方法的入参级别,当Controller的action方法入参注解了RefBean,那么这个参数将会从IOC容器中获取一个对应的实体,传入方法内。IOC提供了第三方接口,用于监控实体bean的初始化过程等功能。关于详细的设计思想将会在对应的模块中介绍。
三、AOP模块
也是通过注解的方式申明一个增强。
@AOP(classRegex="org.jbeer.sample.bean.service.*Impl")
public class TestAspect {
@Before
public void before(InvokeHandler handler){
System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+"before");
}

@After
public void after(InvokeHandler handler,Object ret){
System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+",return:"+ret+"after");
}
@Excep
public void exception(InvokeHandler handler,Exception e){
System.out.println(this.getClass().getName()+handler.getClass().getName()+"."+handler.getInvokeMethod().getName()+",exception:"+e.getMessage());
}}
通过AOP注解表示这是一个增强,并且制定切面,切面可以制定到类级别和方法级别,如果两个属性都没配置,则增强所有IOC容器中的bean实体,切面的定义是大家熟悉的正则表达式。然后依次在方法中注解Before,After,Excep是什么意思,我想我不说应该都知道是什么意思。
四、ORM模块
JBEER采用链式的SQL拼装加上可自定义SQL的方式进行SQL执行,然后ORM转化,提供了导航式的数据库访问。不多说,还是来点代码有意思:

执行插入:
DB.insert(user).execute();
DB.insert(User.class).insert("name", "bieber").execute();
执行更新:
DB.update(user).where("id", OperationType.EQUAL, 23).execute();
执行删除:
DB.delete(User.class).where("id", OperationType.EQUAL, 23);
执行查询:
DB.select(User.class).page(1, 1).selectList();

上面只是展示了简单几个实例,在执行这几个语句之前,必须到对应的实体类里面进行通过Entity和Column进行注解。

五、 关于配置信息加载以及IN18部分
通过实现Configurate接口,告知Jbeer需要加载的配置资源地址以及IN18资源地址,那么JBEER将会将其加载到容器中。通过如下方式注入到Bean中:
@Properties(name="test")
private String test;
@Message(name="test",args={"bieber","tom"})
private String message;


通过Properties和Message注解边可引用制定的配置内容,这两个配置也支持方法级别,在Controller的Action方法入参上面可以配置相关引用信息。

六、 声明式事务 通过在bean的方法上面配置Tx注解来表示这个方法需要进行事务管理,默认的传播机制是PROPAGATION_REQUIRED

七、 关于JBeer测试
当使用
Jbeer
的时候,需要对你的功能进行单元测试,而且测试过程中需要引用
Jbeer
中的
IOC
中实体
bean
,或者是配置信息或者是
in18
内容,或者数据库访问。很简单就可以将
jbeer
嵌入到测试中。只需要测试类实现
JBeerTestHelper
抽象类,实现相关方法,便可以通过注解引用
jbeer
中的资源。

八、关于插件

Jbeer提供了多种插件开发方式,提供了比较丰富的第三方实现的接口,比如视图渲染器只需要实现Render接口,需要具有AOP功能的插件,比如缓存,只需要实现具有插件功能的接口,便可以实现拦截需要的切面。等等.....

【2014-06-20新增】

九、启动项目

jbeer中包含一个jbeer_server模块,该模块将jetty嵌入到了应用中,只需在对应的web项目中实现一个main方法,启动项目即可。代码如下:

public class Start {

public static void main(String[] args) {
IServer server = new JettyServer("src/main/webapp", 8080, "/",1000);
try {
server.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}

上面是制定了resource目录是${PROJECT_HOME}/src/main/webapp下面,服务启动端口是8080,访问上下文跟路径是“/”,jbeer_server支持自动加载修改过后的项目文件,以实现,自动部署修改后的webapp,那么最后一个参数1000是,每秒扫描一下项目的文件变更,如果变更则进行重新部署项目。还提供额默认的服务启动接口,无参的JettyServer构造函数,默认是resource目录是${PROJECT_HOME}/src/main/webapp,上下文路径是“/”,占用端口是8080,不启动扫描项目文件变更,需要手动停止服务,再启动服务,进行重新加载项目变更后的文件内容。其他服务启动接口如下:

public JettyServer()
public JettyServer(long invertalTime)
public JettyServer(String webAppDir, int port, String context)


以上是JBeer各个功能的一个预览,基本上支持了J2EE常规开发的一些需求,可能有些细节上还有不足,希望大家积极反馈意见和问题,从而使得JBeer更加完整。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: