自定义MVC框架中的一些元素

一些注解

@Documented@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Controller {    String value () default "";}@Documented@Target({ElementType.TYPE,ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface RequestMapping {    String value () default "";}@Documented@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Service {    String value () default "";}@Documented@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)public @interface Autowired {    String value () default "";}

解决对象封装

public class Handler {    private Object controller;//Controller对应的类    private Method method;//执行业务的办法    private Pattern pattern;//uri    private Map<String,Integer> paramIndexMapping;//参数和地位的映射    public Handler(Object controller, Method method, Pattern pattern) {        this.controller = controller;        this.method = method;        this.pattern = pattern;        this.paramIndexMapping = new HashMap<>();    }    public Object getController() {        return controller;    }    public void setController(Object controller) {        this.controller = controller;    }    public Method getMethod() {        return method;    }    public void setMethod(Method method) {        this.method = method;    }    public Pattern getPattern() {        return pattern;    }    public void setPattern(Pattern pattern) {        this.pattern = pattern;    }    public Map<String, Integer> getParamIndexMapping() {        return paramIndexMapping;    }    public void setParamIndexMapping(Map<String, Integer> paramIndexMapping) {        this.paramIndexMapping = paramIndexMapping;    }}

自定义DisptchServelet解决代码

public class DispatchServelet extends HttpServlet {    private Properties properties = new Properties();    private List<String> classNames = new ArrayList<>();    private Map<String,Object> ioc =new HashMap<>();    private List<Handler> handlerMapping = new ArrayList<>();    @Override    public void init(ServletConfig config) throws ServletException {        //加载配置文件        String contextConfigLocation = config.getInitParameter("contextConfigLocation");        doLoadConfig(contextConfigLocation);        //扫描相干的类,扫描注解        doScan(properties.getProperty("scanPackage"));        //初始化bean,基于注解        doInstance();        //实现依赖注入        doAutoWired();        //实现处理器映射器,将url和method进行关联        initHandlerMapping();        System.out.println("mvc 初始化实现");            }    //执行的是办法和url办法映射    private void initHandlerMapping() {        if (ioc.isEmpty()){            return;        }        for (Map.Entry<String,Object> entry :ioc.entrySet()){            Class<?> aClass = entry.getValue().getClass();            if (!aClass.isAnnotationPresent(Controller.class)){                continue;            }            String baseUrl = "";            if (aClass.isAnnotationPresent(RequestMapping.class)){                RequestMapping requestMapping = aClass.getAnnotation(RequestMapping.class);                baseUrl=requestMapping.value();            }            Method[] methods= aClass.getMethods();            for (int i=0;i<methods.length;i++){                Method method = methods[i];                if (!method.isAnnotationPresent(RequestMapping.class)){                    continue;                }                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);                String methodUrl = requestMapping.value();                String url = baseUrl+methodUrl;                Handler handler = new Handler(entry.getValue(),method, Pattern.compile(url));                Parameter[] parameters = method.getParameters();                for (int j=0;j<parameters.length;j++){                    Parameter parameter = parameters[j];                    if (parameter.getType().equals(HttpServletRequest.class)||parameter.getType().equals(HttpServletResponse.class)){                        handler.getParamIndexMapping().put(parameter.getType().getSimpleName(),j);                    }else {                        handler.getParamIndexMapping().put(parameter.getName(),j);                    }                }                //实现办法和url的映射关系                handlerMapping.add(handler);            }        }    }    //执行注入局部,同样是做的ioc的局部性能    private void doAutoWired() {        if (ioc.isEmpty()){            return;        }        for (Map.Entry<String,Object> entry :ioc.entrySet()){            Field[] declareFields = entry.getValue().getClass().getDeclaredFields();            for (int i=0;i<declareFields.length;i++){                Field declareField = declareFields[i];                if (!declareField.isAnnotationPresent(Autowired.class)){                    continue;                }                Autowired autowired = declareField.getAnnotation(Autowired.class);                String beanName = autowired.value();                if ("".equals(beanName.trim())){                    beanName=declareField.getType().getName();                }                declareField.setAccessible(true);                try {                    //间接将这个字段的值设置为ioc中曾经示例化的类,                    // 即是实现了ioc中的实例化交给容器来治理的状况                    declareField.set(entry.getValue(),ioc.get(beanName));                } catch (IllegalAccessException e) {                    e.printStackTrace();                }            }        }    }    //执行的是符合要求的类的初始化,实际上是实现的一部分ioc的性能    private void doInstance()  {        if (classNames.size()==0){            return;        }        try {            for (int i=0;i<classNames.size();i++){                String className = classNames.get(i);                Class<?> clazz = Class.forName(className);                if (clazz.isAnnotationPresent(Controller.class)){                    String simpleName = clazz.getSimpleName();                    String lowerFirst = lowerFirst(simpleName);                    Object o = clazz.newInstance();                    //因为controller无别名,所以简略设置成首字母小写就行                    ioc.put(lowerFirst,o);                }else if (clazz.isAnnotationPresent(Service.class)){                    Service service = clazz.getAnnotation(Service.class);                    String beanName =service.value();                    if (!"".equals(beanName.trim())){                        ioc.put(beanName,clazz.newInstance());                    }else {                        beanName = lowerFirst(clazz.getSimpleName());                        ioc.put(beanName,clazz.newInstance());                    }                    Class<?>[] interfaces = clazz.getInterfaces();                    for (int j=0;j<interfaces.length;j++){                        Class<?> ainterface = interfaces[j];                        System.out.println(ainterface.getName());                        //将实现类和接口进行绑定                        ioc.put(ainterface.getName(),clazz.newInstance());                    }                }else {                    continue;                }            }        }catch (Exception e){            e.printStackTrace();        }    }    private  String lowerFirst(String className){       char[] chars = className.toCharArray();       if ('A'<chars[0]&&chars[0]<'Z'){           chars[0]+=32;       }       return new String(chars);    }    private void doScan(String basePackage) {        //获取到指定包下的所有类的类名        String scanPackagePath= Thread.currentThread().getContextClassLoader().getResource("").getPath()+basePackage.replaceAll("\\.","/");        File pack = new File(scanPackagePath);        File [] files = pack.listFiles();        for (File file:files){            if (file.isDirectory()){                doScan(basePackage+"."+file.getName());            }else if (file.getName().endsWith(".class")){                String className = basePackage+"."+file.getName().replaceAll(".class","");                classNames.add(className);            }        }    }    //实现加载web.xml中配置的文件的门路    private void doLoadConfig(String contextConfigLocation) {        InputStream inputStream =this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);        try {            properties.load(inputStream);        } catch (IOException e) {            e.printStackTrace();        }    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        doPost(req,resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        Handler handler = getHander(req);        if (handler==null){            resp.getWriter().write("404 not found");            return;        }        Class<?> [] parameterTypes = handler.getMethod().getParameterTypes();        Object[] paraValues = new Object[parameterTypes.length];        Map<String,String[]> parameterMap = req.getParameterMap();        for (Map.Entry<String,String[]> param:parameterMap.entrySet()){            String value = StringUtils.join(param.getValue(),",");            if (!handler.getParamIndexMapping().containsKey(param.getKey())){                continue;            }            //对应理论参数的地位            Integer index = handler.getParamIndexMapping().get(param.getKey());            paraValues[index]=value;        }        //对应上req,和resp参数的地位        int reqIndex = handler.getParamIndexMapping().get(HttpServletRequest.class.getSimpleName());        paraValues[reqIndex]=req;        int respIndex = handler.getParamIndexMapping().get(HttpServletResponse.class.getSimpleName());        paraValues[respIndex]=resp;        try {            //理论执行的是controller中的办法            handler.getMethod().invoke(handler.getController(),paraValues);            System.out.println("执行controller办法胜利");        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        }    }    private Handler getHander(HttpServletRequest req) {        if (handlerMapping.isEmpty()){            return null;        }        String url =req.getRequestURI();        for (Handler handler:handlerMapping){            Matcher matcher = handler.getPattern().matcher(url);            if (!matcher.matches()){                continue;            }            return handler;        }        return null;    }}

测试代码

public interface DemoService {    String getName(String name);}@Service("demoService")public class DemoServiceImpl implements DemoService {    @Override    public String getName(String name) {        return name;    }}@Controller@RequestMapping("/demo")public class DemoController {    @Autowired    private DemoService demoService;    @RequestMapping("/query")    public String query(HttpServletRequest req, HttpServletResponse resp,String name){        return demoService.getName(name);    }}

web.xml配置

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app>  <display-name>Archetype Created Web Application</display-name>  <servlet>    <servlet-name>mvc</servlet-name>    <servlet-class>com.zhao.mvcframework.servelet.DispatchServelet</servlet-class>    <init-param>      <param-name>contextConfigLocation</param-name>      <param-value>mvc.properties</param-value>    </init-param>  </servlet>  <servlet-mapping>    <servlet-name>mvc</servlet-name>    <url-pattern>/*</url-pattern>  </servlet-mapping></web-app>

mvc.properties的配置

scanPackage=com.zhao.mvcdemo

pom文件的配置

<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.zhao</groupId>  <artifactId>mvc</artifactId>  <version>1.0-SNAPSHOT</version>  <packaging>war</packaging>  <name>mvc Maven Webapp</name>  <!-- FIXME change it to the project's website -->  <url>http://www.example.com</url>  <properties>    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>    <maven.compiler.source>1.8</maven.compiler.source>    <maven.compiler.target>1.8</maven.compiler.target>  </properties>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>4.11</version>      <scope>test</scope>    </dependency>    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>      <scope>provided</scope>    </dependency>    <dependency>      <groupId>org.apache.commons</groupId>      <artifactId>commons-lang3</artifactId>      <version>3.10</version>    </dependency>  </dependencies>  <build>      <plugins>        <plugin>          <groupId>org.apache.tomcat.maven</groupId>          <artifactId>tomcat7-maven-plugin</artifactId>          <version>2.2</version>          <configuration>            <port>8080</port>            <path>/</path>          </configuration>        </plugin>        <plugin>            <groupId>org.apache.maven.plugins</groupId>            <artifactId>maven-compiler-plugin</artifactId>            <version>3.1</version>            <configuration>              <source>1.8</source>              <target>1.8</target>              <encoding>utf-8</encoding>              <compilerArgs>-parameters</compilerArgs>            </configuration>        </plugin>      </plugins>  </build></project>

测试时拜访具体的http://localhost:8080/demo/query?name=zhaozhen 无问题

代码地址为https://github.com/zhendiao/d...

欢送搜寻关注自己与敌人共同开发的微信面经小程序【大厂面试助手】和公众号【微瞰技术】