springMVC实践之简单实践

1、创建注解
MineController
MineAutowired
MineRequestMapping
MineRequestParam
MineService
MineDao

1.1、注入注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MineAutowired {
    String value() default "";
}

1.2、控制注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MineController {
    String value() default "";
}

1.3、访问路径注解
@Target({ElementType.TYPE,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MineRequestMapping {
    String value() default "";
}

1.4、参数注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MineRequestParam {
    String value() default "";
}

1.5、服务注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MineService {
    String value() default "";
}

 

2、创建测试controller、service、dao

2.1、控制层

@MineController
@MineRequestMapping("/test")
public class TestController{

    @MineAutowired("testServiceImpl")
    private TestService testService;

    @MineRequestMapping("/query")
    public void query(HttpServletRequest request, HttpServletResponse response, String name){
        try{
            PrintWriter pw = response.getWriter();
            String result = testService.query(name);
            pw.write(result);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

}

 

2.2、服务层

public interfaceTestService{
   public String query(String name);
}

//JVM Map存放key和实例依赖注入通过key获取实例map.put(“testServiceImpl”,new testServiceImpl())

@MineService("testServiceImpl")
public class TestServiceImpl implement TestService{

@Override
public String query(String name){
return "name="+name;
}
}

 

2.3、数据库交互层

@MineDao(“testDao”)
Public class TestDao{
}

 

3、核心类

public class DispatcherServlet extends HttpServlet {

    List<String> classNames = new ArrayList<>();

    Map<String,Object> beans = new HashMap<>();

    //访问路径-方法
    Map<String,Object> headerMap = new HashMap<>();


    @Override
    public void init() throws ServletException {
        //tomcat启动的时候实例化map、ioc

        //扫描编译好的类路径
        basePackageScan("com.cwc");

        //对classNames扫描到的类实例化
        doInstance();

        //对依赖注入的成员变量赋值
        doAutowired();

        //用户请求路径与方法对应关系 test/query ->method
        doUrlMapping();
    }

    //用户请求路径与方法对应关系
    private void doUrlMapping() {
        for(Map.Entry<String,Object> entry : beans.entrySet()) {
            Object instance = entry.getValue();
            Class<?> clazz = instance.getClass();
            if (clazz.isAnnotationPresent(MineController.class)) {
                MineRequestMapping mapping1 = clazz.getAnnotation(MineRequestMapping.class);
                String classPath = mapping1.value();

                Method[] methods = clazz.getMethods();
                for(Method method :methods){
                    if(method.isAnnotationPresent(MineRequestMapping.class)){
                        MineRequestMapping mapping2 = method.getAnnotation(MineRequestMapping.class);
                        String methodPath = mapping2.value();  //访问路径 /test

                        String requestPath = classPath+methodPath;  //
                        headerMap.put(requestPath,method);
                    }
                }
            }
        }
    }

    //对依赖注入的成员变量赋值
    private void doAutowired() {
        for(Map.Entry<String,Object> entry : beans.entrySet()){
            Object instance = entry.getValue();
            Class<?> clazz = instance.getClass();
            if(clazz.isAnnotationPresent(MineController.class)){
                Field[] fields = clazz.getDeclaredFields();
                for(Field field : fields){
                    if(field.isAnnotationPresent(MineAutowired.class)){
                        MineAutowired autowired = field.getAnnotation(MineAutowired.class);
                        String key = autowired.value();
                        Object bean = beans.get(key);
                        //允许私有变量能访问
                        field.setAccessible(true);
                        try{
                            field.set(instance,bean);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    //对classNames扫描到的类实例化
    private void doInstance() {
        for(String className : classNames){
            String cn = className.replace(".class","");
            try{
                Class<?> clazz = Class.forName(cn);

                if(clazz.isAnnotationPresent(MineController.class)){
                    //控制类
                    Object instance = clazz.newInstance();
                    MineRequestMapping mapping = clazz.getAnnotation(MineRequestMapping.class);
                    String key = mapping.value();
                    //创建Map(访问路径,访问实例)
                    beans.put(key,instance);
                }else if(clazz.isAnnotationPresent(MineService.class)){
                        //服务类
                        Object instance = clazz.newInstance();
                        MineService mapping = clazz.getAnnotation(MineService.class);
                        String key = mapping.value();
                        //创建Map(访问路径,访问实例)
                        beans.put(key,instance);
                }

            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    //扫描编译好的类路径
    private void basePackageScan(String basePackage) {
        //扫描编译好的类路径  ..class
        URL url = this.getClass().getClassLoader().getResource("/"+basePackage.replaceAll("\\.","/"));
        String fileStr = url.getFile();  //E:/cwc/com/test
        File file = new File(fileStr);

        String[] filesStr = file.list();

        //迭代找出所有的文件
        for(String path : filesStr){
            File filePath = new File(fileStr+path);
            if(filePath.isDirectory()){
                basePackageScan(basePackage+"."+path);
            }else{
                classNames.add(basePackage+"."+filePath.getName());
            }
        }
    }


    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String uri = req.getRequestURI();  //全路径: //simple-mvc/test/query
        String context = req.getContextPath();                   //simple-mvc
        String path = uri.replace(context,"");    //访问路径:/test/query

        Method method = (Method) headerMap.get(path);

        Object instance = beans.get("/"+path.split("/")[1]);

        try {
            method.invoke(instance,method);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }


}

 

4、web.xml 配置web.xml配置DispatcherServlet核心类和项目启动执行DispatcherServlet.init方法

<servlet>
<servlet-name>DispatcherServlet< /servlet-class>
<servlet-class>com.cwc.mvc.servlet.DispatcherServlet</servlet-class>
 <!—项目启动的时候执行init方法-->
<load-on-startup>0</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name></servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

 

posted @ 2020-02-13 16:16  N神3  阅读(295)  评论(0编辑  收藏  举报