4、Eternal框架-持有者

持有者Container.java持有,所有的控制器和拦截器实例,多个拦截器构成拦截器链。

初始化控制器:非常简单,在DispatcherServlet初始化时,调用它Container.init(config),init方法里查找所有class文件,有Mapping注解的方法,校验后,即为控制器。

初始化拦截器:同上。Mapping注解有2个参数url,cmi,其中cmi为自定义拦截器(cmi为c:controller,m:me,i:interceptor)。Container.java代码如下:


package cn.eternal.container;

import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


import cn.eternal.annotation.Mapping;
import cn.eternal.config.Config;
import cn.eternal.config.ConfigException;
import cn.eternal.handler.InstanceHandler;
import cn.eternal.handler.MappingHandler;
import cn.eternal.interceptor.EmptyInterceptor;
import cn.eternal.interceptor.Interceptor;
import cn.eternal.renderer.Renderer;
import cn.eternal.util.ConverterUtil;
public class Container {


    private static Log log = LogFactory.getLog(Container.class);
    
    public static Map<MappingHandler,Interceptor[]> interceptors = new HashMap<MappingHandler,Interceptor[]>();
    public static MappingHandler[] MappingHandlers = null;
    public static Map<MappingHandler, InstanceHandler> mhih = new HashMap<MappingHandler, InstanceHandler>();
    private static ConverterUtil converterUtil = new ConverterUtil();
    
    public static void init(final Config config) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
 initControllersAndInterceptors(config);
    }


    static void warnInvalidInstanceHandlerMethod(Method m, String string) {
        log.warn("Init Invalid Controller method '" + m.toGenericString() + "': " + string);
    }


 public static void initControllersAndInterceptors(Config config) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
 ClassLoader cld = Thread.currentThread().getContextClassLoader();
 URL resource = cld.getResource("/");
 File dirs = new File(resource.getFile());
 ArrayList<Class> classList = new ArrayList<Class>();
 findClass(dirs,"",classList);
 findControllersAndInterceptors(classList,config.getInitParameter("interceptors"));
 
 MappingHandlers = mhih.keySet().toArray(new MappingHandler[mhih.size()]);
        Arrays.sort(
                MappingHandlers,
                new Comparator<MappingHandler>() {
                    public int compare(MappingHandler o1, MappingHandler o2) {
                        String u1 = o1.url;
                        String u2 = o2.url;
                        int n = u1.compareTo(u2);
                        if (n==0)
                            throw new ConfigException("Cannot mapping one url '" + u1 + "' to more than one Controller method.");
                        return n;
                    }
                }
        );


    }
 private static void findClass(File dirs,String basePack,ArrayList<Class> classList)
 throws ClassNotFoundException {
 File[] childs = dirs.listFiles();
 for (int i = 0; i < childs.length; i++) {
 String packPath =basePack+childs[i].getName()+".";
 if (childs[i].isDirectory()) {
 findClass(childs[i],packPath,classList);
 } else {
 String className = childs[i].getName();
 if (className.endsWith(".class")) {
 packPath=packPath.replace(".class.", "");
 classList.add(Class.forName(packPath));
 }
 }
 }
 }
 
 private static void findControllersAndInterceptors(ArrayList<Class> classLst,String inters)
 throws InstantiationException, IllegalAccessException, ClassNotFoundException {
 for (int c = 0; c < classLst.size(); c++) {
 Class clazz = classLst.get(c);
 Method mArr[] = clazz.getDeclaredMethods();
 for (Method m:mArr) {
            if (isControllerMethod(m)) {
                Mapping mapping = m.getAnnotation(Mapping.class);
                String url = mapping.url();
                MappingHandler matcher = new MappingHandler(url);
                if (matcher.getArgumentCount()!=m.getParameterTypes().length) {
                    warnInvalidInstanceHandlerMethod(m, "Arguments in URL '" + url + "' does not match the arguments of method.");
                    continue;
                }
                log.info("Init Controller "+m.toGenericString()+" Mapping url '" + url + "'.");
                mhih.put(matcher, new InstanceHandler(clazz.newInstance(), m));
                Class cmi = mapping.cmi();
                String cinters = "";
 if(cmi != null && cmi != EmptyInterceptor.class){
 if(inters != "" && inters != null){
 cinters = ","+cmi.getName();
 log.info("Init Interceptor "+cmi.getName()+" For "+m.toGenericString()+".");
 }
 }
 addInterceptors(matcher,(inters+cinters).split(","));
            }
 }
 }
 }
    static void addInterceptors(MappingHandler matcher,String[] inters) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
    	Interceptor[] interArr = new Interceptor[inters.length];
    	for(int i=0;i<inters.length;i++){
    		interArr[i] = (Interceptor)(Class.forName(inters[i])).newInstance();
    	}
    	interceptors.put(matcher,interArr);
    }


    static boolean isControllerMethod(Method m) {
        Mapping mapping = m.getAnnotation(Mapping.class);
        if (mapping==null)
            return false;
        if (mapping.url().length()==0) {
            warnInvalidInstanceHandlerMethod(m, "Url mapping cannot be empty.");
            return false;
        }
        if (Modifier.isStatic(m.getModifiers())) {
            warnInvalidInstanceHandlerMethod(m, "method is static.");
            return false;
        }
        Class<?>[] argTypes = m.getParameterTypes();
        for (Class<?> argType : argTypes) {
            if (!converterUtil.canConvert(argType)) {
                warnInvalidInstanceHandlerMethod(m, "unsupported parameter '" + argType.getName() + "'.");
                return false;
            }
        }
        Class<?> retType = m.getReturnType();
        if (retType.equals(void.class)
                || retType.equals(String.class)
                || Renderer.class.isAssignableFrom(retType)
        )
            return true;
        warnInvalidInstanceHandlerMethod(m, "unsupported return type '" + retType.getName() + "'.");
        return false;
    }
    public static void destroy() {
       interceptors = null;
       MappingHandlers = null;
       mhih = null;
       converterUtil = null;
    }
 public static MappingHandler[] getMappingHandlers() {
 return MappingHandlers;
 }
 public static Map<MappingHandler, InstanceHandler> getMhih() {
 return mhih;
 }
 public static Interceptor[] getInterceptors(MappingHandler matcher) {
 return interceptors.get(matcher);
 }
}

 
 
 
  
  
  
  


Mapping.java代码:

package cn.eternal.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import cn.eternal.interceptor.EmptyInterceptor;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Mapping {
	String url();
	Class<?> cmi() default EmptyInterceptor.class;
}

你可能感兴趣的:(框架,mvc,REST,控制器)