前言: 首先在gitosc获取到jfinal的源码,本学习笔记使用的是jfinal2.2版本。
从web.xml开始,我们去学习jfinal是怎么从路由请求,到业务处理,最后的返回结果
<!--整个框架的入口-->
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>common.JFinalDemoConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();
// 初始化webRootpath
initPathUtil();
// 启动插件并初始化日志工厂(本章主要讲该部分)
Config.configJFinal(jfinalConfig);
constants = Config.getConstants();
initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();
return true;
}
* jfinalConfig实现类配置常量
*/
public void configConstant(Constants me) {
// 加载少量必要配置,随后可用getProperty(.)获取值
loadPropertyFile("a_little_config.txt");
}
/**
* loadPropertyFile会最终调用该方法
*/
public Properties loadPropertyFile(String fileName, String encoding) {
prop = new Prop(fileName, encoding);
return prop.getProperties();
}
/**
* @param fileName classpath目录下的文件名
* @param encoding 文件编码,默认UTF-8
*/
public Prop(String fileName, String encoding) {
InputStream inputStream = null;
try {
inputStream =Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); // properties.load(Prop.class.getResourceAsStream(fileName));
if (inputStream == null)
throw new IllegalArgumentException("Properties file not found in classpath: " + fileName);
properties = new Properties();
properties.load(new InputStreamReader(inputStream, encoding));
} catch (IOException e) {
throw new RuntimeException("Error loading properties file.", e);
}finally {
if (inputStream != null)
try {
inputStream.close();
} catch (IOException e) {
LogKit.error(e.getMessage(), e);
}
}
}
3.initLoggerFactory();就是初始化logger,运用了工厂模式,有JdkLogger和Loger4jLogger
/**
* 默认使用log4j作为日志实现
*/
static void init() {
if (defaultLogFactory == null) {
try {
Class.forName("org.apache.log4j.Logger");
Class<?> log4jLogFactoryClass =Class.forName("com.jfinal.log.Log4jLogFactory");
defaultLogFactory = (ILogFactory)log4jLogFactoryClass.newInstance(); // return new Log4jLogFactory();
} catch (Exception e) {
defaultLogFactory = new JdkLogFactory();
}
}
}
4.jfinalConfig.configRoute(routes); 配置路由映射
/**
* 设置 controllerKey Controller viewPath 三者的映射关系
* 注意里面的这几个异常,经常会遇到
*/
public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath) {
if (controllerKey == null)
throw new IllegalArgumentException(
"The controllerKey can not be null");
controllerKey = controllerKey.trim();
if ("".equals(controllerKey))
throw new IllegalArgumentException(
"The controllerKey can not be blank");
if (controllerClass == null)
throw new IllegalArgumentException(
"The controllerClass can not be null");
if (!controllerKey.startsWith("/"))
controllerKey = "/" + controllerKey;
if (map.containsKey(controllerKey))
throw new IllegalArgumentException(
"The controllerKey already exists: " + controllerKey);
map.put(controllerKey, controllerClass);
if (viewPath == null || "".equals(viewPath.trim())) // view path is
viewPath = controllerKey;
viewPath = viewPath.trim();
if (!viewPath.startsWith("/")) // "/" added to prefix
viewPath = "/" + viewPath;
if (!viewPath.endsWith("/")) // "/" added to postfix
viewPath = viewPath + "/";
// 获取配置的基础路径(在Constant中进行赋值)
if (baseViewPath != null) // support baseViewPath
viewPath = baseViewPath + viewPath;
// 得到 controller view 的映射
viewPathMap.put(controllerKey, viewPath);
return this;
}