JFinal 初始化过程浅析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JFinal 初始化过程浅析相关的知识,希望对你有一定的参考价值。
从 web 容器进行初始化。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>com.fw.config.MppConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
从 web.xml 可以看出,容器初始化的时候会加载 JFinalFilter 这个类(调用其 init 方法)。下面来看看 JFinalFilter 类做了些什么。
public final class JFinalFilter implements Filter {
private Handler handler;
private String encoding;
private JFinalConfig jfinalConfig;
private Constants constants;
private static final JFinal jfinal = JFinal.me();
private static Log log;
private int contextPathLength;
public void init(FilterConfig filterConfig) throws ServletException {
createJFinalConfig(filterConfig.getInitParameter("configClass"));
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false)
throw new RuntimeException("JFinal init error!");
handler = jfinal.getHandler();
constants = Config.getConstants();
encoding = constants.getEncoding();
jfinalConfig.afterJFinalStart();
String contextPath = filterConfig.getServletContext().getContextPath();
contextPathLength = (contextPath == null || "/".equals(contextPath) ? 0 : contextPath.length());
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
request.setCharacterEncoding(encoding);
String target = request.getRequestURI();
if (contextPathLength != 0)
target = target.substring(contextPathLength);
boolean[] isHandled = {false};
try {
handler.handle(target, request, response, isHandled);
}
catch (Exception e) {
if (log.isErrorEnabled()) {
String qs = request.getQueryString();
log.error(qs == null ? target : target + "?" + qs, e);
}
}
if (isHandled[0] == false)
chain.doFilter(request, response);
}
public void destroy() {
jfinalConfig.beforeJFinalStop();
jfinal.stopPlugins();
}
private void createJFinalConfig(String configClass) {
if (configClass == null)
throw new RuntimeException("Please set configClass parameter of JFinalFilter in web.xml");
Object temp = null;
try {
temp = Class.forName(configClass).newInstance();
} catch (Exception e) {
throw new RuntimeException("Can not create instance of class: " + configClass, e);
}
if (temp instanceof JFinalConfig)
jfinalConfig = (JFinalConfig)temp;
else
throw new RuntimeException("Can not create instance of class: " + configClass + ". Please check the config in web.xml");
}
static void initLog() {
log = Log.getLog(JFinalFilter.class);
}
}
1. createJFinalConfig 创建自定义配置类的一个实例
这个方法中的参数正是 web.xml 中的 JFinalFilter 的初始化参数,它继承于 JFinalConfig。
调用此方法会创建出一个 JFinalConfig 实例。
2. jfinal.init 加载配置并且初始化各个 JFinal 组件
代码如下:
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
initPathUtil();
Config.configJFinal(jfinalConfig);
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
(1) 初始化项目根路径 contextPath
(2) Config.configJFinal 加载自定义配置(配置常量、添加 handler、添加 routes、添加插件、开启插件、添加 Interceptor),代码如下:
static void configJFinal(JFinalConfig jfinalConfig) {
jfinalConfig.configConstant(constants); initLogFactory();
jfinalConfig.configRoute(routes);
jfinalConfig.configPlugin(plugins); startPlugins(); // very important!!!
jfinalConfig.configInterceptor(interceptors);
jfinalConfig.configHandler(handlers);
}
public class MppConfig extends JFinalConfig {
//配置常量
public void configConstant(Constants me) {
PropKit.use("jdbc.properties");
me.setDevMode(PropKit.getBoolean("devMode", false));
}
//配置路由
public void configRoute(Routes me) {
me.add(new RoutesMapping());
}
public static C3p0Plugin createC3p0Plugin() {
return new C3p0Plugin(PropKit.get("jdbcUrl"), PropKit.get("user"), PropKit.get("password").trim());
}
//配置插件
public void configPlugin(Plugins me) {
// 配置C3p0数据库连接池插件
C3p0Plugin C3p0Plugin = createC3p0Plugin();
me.add(C3p0Plugin);
// 配置ActiveRecord插件
ActiveRecordPlugin arp = new ActiveRecordPlugin(C3p0Plugin);
me.add(arp);
// 配置属性名(字段名)大小写不敏感容器工厂 oracle
arp.setContainerFactory(new CaseInsensitiveContainerFactory());
//缓存插件
me.add(new EhCachePlugin());
// 所有配置在 MappingKit 中搞定
ModelMapping.mapping(arp);
}
//配置全局拦截器
public void configInterceptor(Interceptors me) {
me.add(new SessionInViewInterceptor());//session拦截器,用于在View模板中取出session值
}
//配置处理器,接管所有 web 请求
public void configHandler(Handlers me) {
me.add(new ContextPathHandler("contextPath"));//设置上下文路径
}
//系统启动完成后回调,如创建调度线程
public void afterJFinalStart(){}
//系统关闭前回调,如写回缓存
public void beforeJFinalStop(){}
}
(3) 初始化 ActionMapping、Handler、Render、等。
以上是关于JFinal 初始化过程浅析的主要内容,如果未能解决你的问题,请参考以下文章