JFinal 源码导读第三天(2) initActionMapping

1.接上面文章的内容initActionMapping();该方法我会详细讲解

	private void initActionMapping() {
		actionMapping = new ActionMapping(Config.getRoutes(), Config.getInterceptors());
		actionMapping.buildActionMapping();
	}
	ActionMapping(Routes routes, Interceptors interceptors) {
		this.routes = routes;
		this.interceptors = interceptors;
	}
2.上面的actionMapping.buildActionMapping();我会详细介绍
private final Map<String, Action> mapping = new HashMap<String, Action>();
void buildActionMapping() {
		mapping.clear();
		Set<String> excludedMethodName = buildExcludedMethodName();
		InterceptorBuilder interceptorBuilder = new InterceptorBuilder();
		Interceptor[] defaultInters = interceptors.getInterceptorArray();
		interceptorBuilder.addToInterceptorsMap(defaultInters);
		for (Entry<String, Class<? extends Controller>> entry : routes.getEntrySet()) {
			Class<? extends Controller> controllerClass = entry.getValue();
			Interceptor[] controllerInters = interceptorBuilder.buildControllerInterceptors(controllerClass);
			Method[] methods = controllerClass.getMethods();
			for (Method method : methods) {
				String methodName = method.getName();
				if (!excludedMethodName.contains(methodName) && method.getParameterTypes().length == 0) {
					Interceptor[] methodInters = interceptorBuilder.buildMethodInterceptors(method);
					Interceptor[] actionInters = interceptorBuilder.buildActionInterceptors(defaultInters, controllerInters, controllerClass, methodInters, method);
					String controllerKey = entry.getKey();
					
					ActionKey ak = method.getAnnotation(ActionKey.class);
					if (ak != null) {
						String actionKey = ak.value().trim();
						if ("".equals(actionKey))
							throw new IllegalArgumentException(controllerClass.getName() + "." + methodName + "(): The argument of ActionKey can not be blank.");
						
						if (!actionKey.startsWith(SLASH))
							actionKey = SLASH + actionKey;
						
						if (mapping.containsKey(actionKey)) {
							warnning(actionKey, controllerClass, method);
							continue;
						}
						
						Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
						mapping.put(actionKey, action);
					}
					else if (methodName.equals("index")) {
						String actionKey = controllerKey;
						
						Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
						action = mapping.put(actionKey, action);
						
						if (action != null) {
							warnning(action.getActionKey(), action.getControllerClass(), action.getMethod());
						}
					}
					else {
						String actionKey = controllerKey.equals(SLASH) ? SLASH + methodName : controllerKey + SLASH + methodName;
						
						if (mapping.containsKey(actionKey)) {
							warnning(actionKey, controllerClass, method);
							continue;
						}
						
						Action action = new Action(controllerKey, actionKey, controllerClass, method, methodName, actionInters, routes.getViewPath(controllerKey));
						mapping.put(actionKey, action);
					}
				}
			}
		}
		
		// support url = controllerKey + urlParas with "/" of controllerKey
		Action actoin = mapping.get("/");
		if (actoin != null)
			mapping.put("", actoin);
	}
3.上面的类比较长,我会结合我的例子来讲

第一个方法buildExcludedMethodName,代码很简单,就是将Controller类中方法无参数的取出来放到excludeMethodName,主要用在下面的判断,我这里简要介绍,就是我们继承Controller的自己类中的方法取出来

	
	private Set<String> buildExcludedMethodName() {
		Set<String> excludedMethodName = new HashSet<String>();
		Method[] methods = Controller.class.getMethods();
		for (Method m : methods) {
			if (m.getParameterTypes().length == 0)
				excludedMethodName.add(m.getName());
		}
		return excludedMethodName;
	}
	

4.上面两段代码非常简单,自己看看就明白啦
InterceptorBuilder interceptorBuilder = new InterceptorBuilder();
Interceptor[] defaultInters = interceptors.getInterceptorArray();
5.interceptorBuilder.addToInterceptorsMap(defaultInters);这个代码我详细讲一下

@SuppressWarnings("unchecked")
	void addToInterceptorsMap(Interceptor[] defaultInters) {
		for (Interceptor inter : defaultInters)
			intersMap.put((Class<Interceptor>)inter.getClass(), inter);
	}
defaultInters的类就是全局的拦截器,对所有action都是有效的,就是我们下面配置的
	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		me.add(new BlogInterceptor1());
		me.add(new BlogInterceptor2());
	}
	
6.routes.getEntrySet()就是我前面配置的, 在我的例子里面就是就是下面map.put中
private final Map<String, Class<? extends Controller>> map = new HashMap<String, Class<? extends Controller>>();
public Set<Entry<String, Class<? extends Controller>>> getEntrySet() {
		return map.entrySet();
	}
map.put("/", "CommonController.class");
map.put("/blog","BlogController.class")
7.Class<? extends Controller> controllerClass = entry.getValue();
获取到CommonController.class
8.interceptorBuilder.buildControllerInterceptors(controllerClass);这段代码就是相当于
	/**
	 * Build interceptors of Controller
	 */
	Interceptor[] buildControllerInterceptors(Class<? extends Controller> controllerClass) {
		Before before = controllerClass.getAnnotation(Before.class);
		return before != null ? createInterceptors(before) : NULL_INTERCEPTOR_ARRAY;
	}
	/**
	 * Create interceptors with Annotation of Before. Singleton version.
	 */
	private Interceptor[] createInterceptors(Before beforeAnnotation) {
		Interceptor[] result = null;
		@SuppressWarnings("unchecked")
		Class<Interceptor>[] interceptorClasses = (Class<Interceptor>[]) beforeAnnotation.value();
		if (interceptorClasses != null && interceptorClasses.length > 0) {
			result = new Interceptor[interceptorClasses.length];
			for (int i=0; i<result.length; i++) {
				result[i] = intersMap.get(interceptorClasses[i]);
				if (result[i] != null)
					continue;
				
				try {
					result[i] = (Interceptor)interceptorClasses[i].newInstance();
					intersMap.put(interceptorClasses[i], result[i]);
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
		return result;
	}
相当于获取类上面的Before的注解,并且放入到 intersMap中
controllerInters相当于自定义Controller上面的注解信息,BlogInterceptor3.class和BlogInterceptor4.class
private Map<Class<Interceptor>, Interceptor> intersMap = new HashMap<Class<Interceptor>, Interceptor>();
/**
 * BlogController
 * 注意:在实际项目中业务与sql需要写在Model中,此demo仅为示意,故将sql写在了Controller中
 */
@Before({BlogInterceptor3.class,BlogInterceptor4.class})
public class BlogController extends Controller {

今天就介绍到这里,明天继续接下来的代码,我会详细的讲,如果谁有问题,请留言,我会及时回复




你可能感兴趣的:(jFinal)