ioc容器:Inverse of Control (控制反转) 负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需在代码中new相关的对象,应用程序由IOC容器进行组装。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做
配置阶段:web.xml
DispatcherServlet(spring web开发中的入口)
application.xml 路径(配置spring启动前所有需要加载的bean)
url-pattern(方便匹配用户浏览器的输入的地址)
初始化阶段: init()(由web容器自动调用servlet的初始化方法)
加载 application.xml
初始化IOC容器 (该容器就是一个map<String,Object>)
依赖注入DI (@Autowired)
初始化HandleMapping (就是map<String,Method(handler)>存储@RequestMapping配置url,就是根据用户请求的url,匹配到.对应的吧方法,在根据反射调用方法)
运行时阶段:Service(Request,Response) (等待用户请求,随机待命阶段,只要用户请求,就会自动调用doService,线程阻塞)
request.getURI()获得用户请求的URL
匹配URL和其对应的Method
调用method (利用反射机制动态的调用method)
利用response将调用结果输出到浏览器
java注解详解:https://blog.youkuaiyun.com/suyu_yuan/article/details/52634528
手写spring源码:
项目结构:
注解类如下:
LController
//@interface这是注解接口
//LControlleri给自己的Controller加上版权
//ElementType.TYPE表示该注解只能作用到类上
@Target({ElementType.TYPE})
//RetentionPolicy.RUNTIME运行时阶段可用
@Retention(RetentionPolicy.RUNTIME)
//@Documented说明该注解将被包含在javadoc中
@Documented
public @interface LController {
//注解的参数是字符串,默认值为空。
//给注解添加字符串变量,默认值为空
String value() default "";
}
LAutowried
//ElementType.FIELD只能作用于字段上
@Target({ElementType.FIELD})
//运行时阶段可用
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LAutowried {
}
LRequestMapping
//ElementType.TYPE表示该注解作用到类上,ElementType.METHOD该注解作用到方法上
@Target({ElementType.TYPE,ElementType.METHOD})
//运行时阶段可用
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LRequestMapping {
String value() default "";
}
//ElementType.PARAMETER该注解作用到参数上
@Target({ElementType.PARAMETER})
//运行时阶段可用
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LRequestParam {
String value() default "";;
}
@Target({ElementType.TYPE})
//RetentionPolicy.RUNTIME运行时阶段可用
@Retention(RetentionPolicy.RUNTIME)
//@Documented说明该注解将被包含在javadoc中
@Documented
public @interface LService {
String value() default "";
}
在写一个充当拦截器的servlet ---------------LDispatcherServlet
public class LDispatcherServlet extends HttpServlet {
@Override
public void init(ServletConfig config) throws ServletException {
//1.加载配置文件
//2.根据配置文件扫描所有的相关的类
//3.初始化所有的相关类的实例,并且将其放入到IOC容器中(即map中)
//4.自动实现依赖注入,加了@Autowried的都注入进来
//5.初始化handleMapping
//6.等待请求
System.out.println("------l mvc is init--------");
}
@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 {
}
}
web.xml中配置LDispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>lmvc</servlet-name>
<servlet-class>com.lmj.springdim.mvcframework.servlet.LDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>application.properties</param-value>
</init-param>
<!-- load-on-startup 元素标记容器是否应该在web应用程序启动的时候就加载这个servlet,(实例化并调用其init()方法)。
它的值必须是一个整数,表示servlet被加载的先后顺序。-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>lmvc</servlet-name>
<!--任何url都要经过这个拦截-->
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
启动项目:发现打印出: