先从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>
进入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());
}
第一行代买调用了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");
}
createJFinalConfig里面逻辑很简单,取出配置在web.xml中我们自己写MianConfig类进行实例化。
接着看init方法
if (jfinal.init(jfinalConfig, filterConfig.getServletContext()) == false)
throw new RuntimeException("JFinal init error!");
这里又有一个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;
}
这里才是整个框架真正初始化的地方
private void initPathUtil() {
String path = servletContext.getRealPath("/");
PathKit.setWebRootPath(path);
}
这行代码没什么营养,看看即可
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);
}
这里的逻辑也简单,在Config类中创建了五个单例对象,把我们自己写MianConfig中的路径信息、拦截器、数据库关系映射等信息写到了对应的单例对象中。
接下来看下我们自己的MianConfig类
@Override
public void configConstant(Constants me) {
loadPropertyFile("sysconfig.txt");
me.setDevMode(getPropertyToBoolean("devMode", false));
}
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();
}
其中提供了getProperty方法,方便我们从配置文件中获取相应的值
继续看
@Override
public void configRoute(Routes me) {
me.add(new AppRoute());
}
看下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;
}
第一行代码 routes.config(); // very important!!!
作者写了行注释very important!!!
/**
* you must implement config method and use add method to config route
*/
public abstract void config();
一个抽象方法,子类实现,添加相应的Controller到Routes中。看一个实例
public final class AppRoute extends Routes {
@Override
public void config() {
this.add("/user", UserAction.class);
}
}
在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;
}
点击查看更多内容
13人点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦