这里写目录标题
- 1. 手写MVC框架之SpringMVC原理回顾
- 2. 手写MVC框架之注解开发
- 3. 手写MVC框架之流程结构开发
- 4. 手写MVC框架之doLoadConfig开发
- 5. 手写MVC框架之doScan扫描类
- 6. 手写MVC框架之doInstance实例化
- 7. 手写MVC框架之doAutowird实例化
- 8. 手写MVC框架之initHandleMapping实例化
- 9. 手写MVC框架之初始化流程初步测试
- 10. 手写MVC框架之initHandleMapping问题分析
- 11. 手写MVC框架之Handle封装引入
- 12. 手写MVC框架之initHandleMapping改造
- 13. 手写MVC框架之请求处理开发
- 14. 手写MVC框架之整体测试
1. 手写MVC框架之SpringMVC原理回顾
2. 手写MVC框架之注解开发
创建一个自定义Servlet
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class MyDispatcherServlet extends HttpServlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
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>lagoumvc</servlet-name>
<servlet-class>com.lagou.mvcframework.MyDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>lagoumvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutowired {
String value() default "";
}
import java.lang.annotation.*;
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyController {
String value() default "";
}
import java.lang.annotation.*;
@Documented
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRequestMapping {
String value() default "";
}
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyService {
String value() default "";
}
3. 手写MVC框架之流程结构开发
@Override
public void init(ServletConfig servletConfig) throws ServletException {
// 1 、加载配置文件 获取一些配置的信息,如包扫描的路径
// 这里为了简单 使用 将 配置写在 properties 文件中
// 2、扫描相关的类,扫描注解
// 3、 初始化bean对象 (实现ioc容器,基于注解)
// 4、实现依赖注入
// 5、 构造一个HandlerMapping ,将配置好的url 和 Method 建立映射关系
System.out.println("my mvc build successful!!");
}
4. 手写MVC框架之doLoadConfig开发
<servlet>
<servlet-name>lagoumvc</servlet-name>
<servlet-class>com.lagou.mvcframework.MyDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 这里不能 使用 classpath: 暂时 不做 classpath 的处理 -->
<param-value>servlet.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>lagoumvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
// 配置一个
private Properties properties = new Properties();
private void doLoadConfig(String contextConfigLocation) {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);
try {
properties.load(resourceAsStream);
} catch (IOException e) {
e.printStackTrace();
}
}
5. 手写MVC框架之doScan扫描类
//缓存扫描到的类 全限定名
private List<String> classNames = new ArrayList<>();
private void doScan(String scanPackage) {
String path =Thread.currentThread().getContextClassLoader().getResource("").getPath()+ scanPackage.replace("\\.","/");
File pack = new File(path);
File[] files = pack.listFiles();
for (File file : files) {
// 如果是文件夹 递归
if(file.isDirectory()){
doScan(scanPackage + file.getName());
}else if(file.getName().endsWith(".class")){
String className = scanPackage + "." +file.getName().replaceAll(".class","");
classNames.add(className);
}
}
}
6. 手写MVC框架之doInstance实例化
public interface DemoService {
String get(String name);
}
import com.lagou.annotaiton.MyService;
import com.lagou.service.DemoService;
@MyService
public class DemoServiceImpl implements DemoService {
@Override
public String get(String name) {
System.out.println(name);
return "serviceimpl --- " +name ;
}
}
把整个方法 try catch
7. 手写MVC框架之doAutowird实例化
8. 手写MVC框架之initHandleMapping实例化
private void initHandleMapping() {
if(ioc.isEmpty()) return;
// 维护 ioc 容器类之间的关系
try{
for ( Map.Entry<String,Object> entry : ioc.entrySet()){
Class<?> aClass = entry.getValue().getClass();
// 判断是否 ioc容器是否 包含 MyRequestMapping 注解
if ( aClass.isAnnotationPresent(MyRequestMapping.class) ){
MyRequestMapping annotation = aClass.getAnnotation(MyRequestMapping.class);
String baseUrl = annotation.value();
Method[] methods = aClass.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(MyRequestMapping.class)){
MyRequestMapping methodAnnotation = method.getAnnotation(MyRequestMapping.class);
String methodUrl = methodAnnotation.value();
String url = baseUrl + methodUrl;
handleMapping.put(url,method);
}
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
9. 手写MVC框架之初始化流程初步测试
10. 手写MVC框架之initHandleMapping问题分析
11. 手写MVC框架之Handle封装引入
12. 手写MVC框架之initHandleMapping改造
13. 手写MVC框架之请求处理开发
14. 手写MVC框架之整体测试