您的位置:首页 > 其它

jfinal源码解析

2017-07-31 19:08 260 查看
JFinal是一个Java极速开发框架,配置简单 

先从web.xml看起,其中配置了一个过滤器,过滤器中配置项目中我们自己写的核心配置类
<?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"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<filter>
<filter-name>jfinal</filter-name>
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
<init-param>
<param-name>configClass</param-name>
<param-value>com.demo.MainConfig</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>jfinal</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

配置文件中的 com.demo.MainConfig 是我们自己写的项目配置类的全路径名 

进入com.jfinal.core.JFinalFilter中的init方法
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());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

第一行代买调用了createJFinalConfig方法
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");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

createJFinalConfig里面逻辑很简单,取出配置在web.xml中我们自己写MianConfig类进行实例化。 

接着看init方法
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false)
throw new RuntimeException("JFinal init error!");
1
2

这里又有一个init方法
boolean init(JFinalConfig jfinalConfig, ServletContext servletContext) {
this.servletContext = servletContext;
this.contextPath = servletContext.getContextPath();

initPathUtil();

Config.configJFinal(jfinalConfig);  // start plugin and init log factory in this method
constants = Config.getConstants();

initActionMapping();
initHandler();
initRender();
initOreillyCos();
initTokenManager();

return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

这里才是整个框架真正初始化的地方
private void initPathUtil() {
String path = servletContext.getRealPath("/");
PathKit.setWebRootPath(path);
}
1
2
3
4

这行代码没什么营养,看看即可 

Config.configJFinal(jfinalConfig);
private static final Constants constants = new Constants();
private static final Routes routes = new Routes(){public void config() {}};
private static final Plugins plugins = new Plugins();
private static final Interceptors interceptors = new Interceptors();
private static final Handlers handlers = new Handlers();
private static Log log;

// prevent new Config();
private Config() {
}

/*
* Config order: constant, route, plugin, interceptor, handler
*/
static void configJFinal(JFinalConfig jfinalConfig) {
jfinalConfig.configConstant(constants);             initLogFactory();
jfinalConfig.configRoute(routes);
jfinalConfig.configPlugin(plugins);                 startPlugins(); // very important!!!
jfinalConfig.configInterceptor(interceptors);
jfinalConfig.configHandler(handlers);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

这里的逻辑也简单,在Config类中创建了五个单例对象,把我们自己写MianConfig中的路径信息、拦截器、数据库关系映射等信息写到了对应的单例对象中。 

接下来看下我们自己的MianConfig类
@Override
public void configConstant(Constants me) {
loadPropertyFile("sysconfig.txt");
me.setDevMode(getPropertyToBoolean("devMode", false));
}
1
2
3
4
5

configConstant一般用来加载我们的配置文件(配置文件中一般放置一些数据库连接信息,初始化信息等)loadPropertyFile中的逻辑也很简单
public Properties loadPropertyFile(File file) {
return loadPropertyFile(file, Const.DEFAULT_ENCODING);
}

public Properties loadPropertyFile(File file, String encoding) {
prop = new Prop(file, encoding);
return prop.getProperties();
}
1
2
3
4
5
6
7
8
9

其中提供了getProperty方法,方便我们从配置文件中获取相应的值 

继续看
@Override
public void configRoute(Routes me) {
me.add(new AppRoute());
}
1
2
3
4

看下Routes的add方法
public Routes add(Routes routes) {
if (routes != null) {
routes.config();    // very important!!!

for (Entry<String, Class<? extends Controller>> e : routes.map.entrySet()) {
String controllerKey = e.getKey();
if (this.map.containsKey(controllerKey)) {
throw new IllegalArgumentException("The controllerKey already exists: " + controllerKey);
}

this.map.put(controllerKey, e.getValue());
this.viewPathMap.put(controllerKey, routes.getViewPath(controllerKey));
}
}
return this;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

第一行代码 routes.config(); // very important!!! 

作者写了行注释very important!!!
/**
* you must implement config method and use add method to config route
*/
public abstract void config();
1
2
3
4

一个抽象方法,子类实现,添加相应的Controller到Routes中。看一个实例
public final class AppRoute extends Routes {

@Override
public void config() {
this.add("/user", UserAction.class);
}
}
1
2
3
4
5
6
7

在config中又调用了Routes中的add方法
public Routes add(String controllerKey, Class<? extends Controller> controllerClass) {
return add(controllerKey, controllerClass, controllerKey);
}
public Routes add(String controllerKey, Class<? extends Controller> controllerClass, String viewPath) {
if (controllerKey == null)
throw new IllegalArgumentException("The controllerKey can not be null");
// if (controllerKey.indexOf(".") != -1)
// throw new IllegalArgumentException("The controllerKey can not contain dot character: \".\"");
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 controllerKey by default
viewPath = controllerKey;

viewPath = viewPath.trim();
if (!viewPath.startsWith("/"))                  // "/" added to prefix
viewPath = "/" + viewPath;

if (!viewPath.endsWith("/"))                    // "/" added to postfix
viewPath = viewPath + "/";

if (baseViewPath != null)                       // support baseViewPath
viewPath = baseViewPath + viewPath;

viewPathMap.put(controllerKey, viewPath);
return this;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: