本系列博文,将会一步一步介绍如何构建一个轻量级的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的“一寸免冠照片”来给你们瞅瞅 html
看了JBeer的仪容以后,那么下面大概介绍一下各个功能吧。 java
在介绍各个功能以前,仍是先废话一下。JBEER是追求极少的配置文件,这是借鉴了JFinal的风格。须要使用JBEER,只须要将项目依赖jbeer的jar包,而后在web.xml中配置以下信息便可 git
<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的包内或者子包内。下面给出了一个实例: web
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来进行开发了。 正则表达式
1、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),这样当请求的时候将会自动将路径对应的占位符内容看成入参传入。具体细节,后面会在每一个单独模块总介绍。 restful
2、IOC模块 mvc
IOC经过Bean注解申明是一个IOC的bean实体,经过RefBean代表应用IOC容器中的一个实体。很少说,直接粘贴处实例代码。 app
@Bean public class UserService { @RefBean private CodeService codeService; public String getName(){ return codeService.hello()+" world"; } }RefBean注解是能够定义在方法的入参级别,当Controller的action方法入参注解了RefBean,那么这个参数将会从IOC容器中获取一个对应的实体,传入方法内。IOC提供了第三方接口,用于监控实体bean的初始化过程等功能。关于详细的设计思想将会在对应的模块中介绍。
3、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是什么意思,我想我不说应该都知道是什么意思。
4、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进行注解。
5、 关于配置信息加载以及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方法入参上面能够配置相关引用信息。
6、 声明式事务
经过在bean的方法上面配置Tx注解来表示这个方法须要进行事务管理,默认的传播机制是PROPAGATION_REQUIRED
7、 关于JBeer测试
当使用 Jbeer 的时候,须要对你的功能进行单元测试,并且测试过程当中须要引用 Jbeer 中的 IOC 中实体 bean ,或者是配置信息或者是 in18 内容,或者数据库访问。很简单就能够将 jbeer 嵌入到测试中。只须要测试类实现 JBeerTestHelper 抽象类,实现相关方法,即可以经过注解引用 jbeer 中的资源。
8、关于插件
Jbeer提供了多种插件开发方式,提供了比较丰富的第三方实现的接口,好比视图渲染器只须要实现Render接口,须要具备AOP功能的插件,好比缓存,只须要实现具备插件功能的接口,即可以实现拦截须要的切面。等等.....
【2014-06-20新增】
9、启动项目
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更加完整。