package org.chengxi.mvnframework.servlet;
import org.chengxi.mvnframework.annotation.*;
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.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Handler{
//保存方法对应的实例
protected Object controller;
//保存映射的方法
protected Method method;
protected Pattern pattern;
//保存方法的参数顺序
protected Map<String, Integer> paramIndexMapping;
protected Handler(Object controller, Method method, Pattern pattern){
this.controller = controller;
this.method = method;
this.pattern = pattern;
paramIndexMapping = new HashMap<String, Integer>();
putParamIndexMapping(method);
}
//提取方法中加了@RequestParam注解的参数
public void putParamIndexMapping(Method method){
//提取方法中加了注解的参数
Annotation[][] pa = method.getParameterAnnotations();
for(int i=0; i<pa.length; i++){
for(Annotation a: pa[i]){
if(a instanceof RequestParam){
String paramName = ((RequestParam) a).value();
if(!"".equals(paramName)){
paramIndexMapping.put(paramName,i);
}
}
}
}
//提取方法中的resp和req参数
Class<?>[] paramsTypes = method.getParameterTypes();
for(int i=0; i<paramsTypes.length; i++){
Class<?> type = paramsTypes[i];
if(type == HttpServletRequest.class || type == HttpServletResponse.class){
paramIndexMapping.put(type.getName(), i);
}
}
}
}
public class DispatcherServlet extends HttpServlet {
private Properties p = new Properties();
private List<String> classNames = new ArrayList<String>();
private Map<String, Object> ioc = new HashMap<String, Object>();
private List<Handler> handlerMapping = new ArrayList<Handler>();
@Override
public void init(ServletConfig config) throws ServletException {
//获取属性文件,类似于获取application.xml文件所在路径
String application = config.getInitParameter("contextConfigLocation");
//1.加载配置文件
try {
doLoadConfig(application);
} catch (IOException e) {
e.printStackTrace();
}
//扫描配置文件中描述的相关的所有类
doScanner(p.getProperty("scanPackage"));
//3.实例化所有被扫描到的类并且存放到IOC容器中(自己实现容器)
try {
doInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
//4.依赖注入,DI从IOC容器中找到加上了@Autowired注解的属性并找到其在IOC容器中对应的实例
try {
doAutowired();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//5.把在@Controller中加了@RequestMapping注解的方法和URL构造成一个对应关系map
initHandlerMapping();
System.out.println(ioc);
System.out.println(handlerMapping);
System.out.println(classNames);
}
@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
//6.等待用户请求,根据url找到对应的method,通过反射机制进行调用并执行返回响应
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
doDispatcher(req, resp);
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
private void doLoadConfig(String location) throws IOException {
InputStream is = this.getClass().getClassLoader().
getResourceAsStream(location);
p.load(is);
if(null != is){
is.close();
}
}
private void doScanner(String packageName){
URL url = this.getClass().getClassLoader().getResource("/" + packageName.replaceAll("\\.","/"));
File dir = new File(url.getFile());
for(File f: dir.listFiles()){
if(f.isDirectory()){
doScanner(packageName + "." + f.getName());
}
else{
classNames.add(packageName + "." + f.getName().replace(".class","").trim());
}
}
}
private void doInstance() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
if(classNames.isEmpty()){
return ;
}
for(String className: classNames){
Class<?> clazz = Class.forName(className);
//只初始化controller容器和service容器
if(clazz.isAnnotationPresent(Controller.class)){
//默认首字母小写称为beanName
String beanName = lowerFirst(clazz.getSimpleName());
ioc.put(beanName, clazz.newInstance());
}
else if(clazz.isAnnotationPresent(Service.class)){
//第一种形式:默认首字母小写
//第二种形式:注解自己提供名字(优先)
//第三种形式:利用接口本身全称作为key,其对应实现类作为值
Service service = clazz.getAnnotation(Service.class);
String beanName = service.value();
Object instance = clazz.newInstance();
//注解本身提供名字@service("sss")
if(!"".equals(beanName.trim())){
ioc.put(beanName, instance);
continue;
}
Class<?>[] interfaces = clazz.getInterfaces();
for(Class<?> inter: interfaces){
ioc.put(inter.getName(), instance);
}
}
}
}
private void doAutowired() throws IllegalAccessException {
if(ioc.isEmpty()){
return;
}
for(Map.Entry<String, Object> entry: ioc.entrySet()){
//获取所有字段
Field[] fields = entry.getValue().getClass().getDeclaredFields();
for(Field field: fields){
if(!field.isAnnotationPresent(Autowired.class)){
continue;
}
Autowired autowired = field.getAnnotation(Autowired.class);
String beanName = autowired.value().trim();
if("".equals(beanName)){
beanName = field.getType().getName();
}
//即使是private也要进行强制注入
field.setAccessible(true);
//开始赋值
field.set(entry.getValue(), io
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
mymvc.zip (47个子文件)
mymvc
pom.xml 1001B
target
MyMVC
META-INF
MANIFEST.MF 98B
WEB-INF
web.xml 814B
classes
application.properties 30B
org
chengxi
mvnframework
annotation
Service.class 504B
RequestMapping.class 532B
RequestParam.class 519B
Autowired.class 509B
Controller.class 510B
servlet
DispatcherServlet.class 10KB
Handler.class 2KB
demo
action
DemoAction.class 2KB
service
IDemoService.class 185B
impl
DemoService.class 793B
index.jsp 57B
classes
application.properties 30B
org
chengxi
mvnframework
annotation
Service.class 504B
RequestMapping.class 532B
RequestParam.class 519B
Autowired.class 509B
Controller.class 510B
servlet
DispatcherServlet.class 10KB
Handler.class 2KB
demo
action
DemoAction.class 2KB
service
IDemoService.class 185B
impl
DemoService.class 793B
generated-sources
annotations
src
main
webapp
WEB-INF
web.xml 814B
index.jsp 57B
resources
application.properties 30B
java
org
chengxi
mvnframework
annotation
RequestMapping.java 337B
RequestParam.java 312B
Controller.java 302B
Autowired.java 305B
Service.java 299B
servlet
DispatcherServlet.java 11KB
demo
action
DemoAction.java 1KB
service
IDemoService.java 112B
impl
DemoService.java 300B
.idea
misc.xml 566B
modules.xml 250B
compiler.xml 622B
workspace.xml 42KB
libraries
Maven__junit_junit_3_8_1.xml 462B
Maven__javax_servlet_servlet_api_2_5.xml 522B
artifacts
MyMVC_war.xml 281B
MyMVC_war_exploded.xml 632B
inspectionProfiles
MyMVC.iml 1KB
共 47 条
- 1
资源评论
19年,重新开始写
- 粉丝: 193
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于keras+fasterRCNN,在VOC格式的口罩数据集上训练,检测人群中有无戴口罩python源码+模型
- 基于opencv+qt5机器视觉的传统缺陷检测, 即采用标准图片和待测图片进行pixel to pixel的XOR操作源码+文档
- 管道内检测缺陷数据库管理系统源码+文档说明+sln
- 毕业设计-低功耗STM32F411开发板(原理图+PCB源文件+官方例程+驱动等)源码+文档说明+截图
- 基于yolov5-tensorRT检测+发动机缸体内壁缺陷检测系统源码+文档说明
- 基于C++实现的锂电池缺陷检测源码+文档说明
- push_version
- 软件自制图像批量压缩工具
- 经典缺陷检测算法源码整理包含PaDiM(2020ICPR)、PatchCore(2022CVPR)、SimpleNet+文档说明
- 基于深度学习的抗梯度噪声的缺陷检测器python源码+文档说明+模型的预训练
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功