Step1 中央调度器的类
public class GPDispatcherServlet extends HttpServlet {
@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 {
try{
doDispatch(req,resp);
} catch(Exception e){
e.printStackTrace();
resp.getWriter().write("500"+Arrays.toString(e.getStackTrace()));
}
}
private Properties contextConfig=new Properties();
private List<String> classNames=new ArrayList<>();
private Map<String,Method> handlerMapping=new HashMap<>();
private Map<String,Object> ioc=new HashMap<>();
Step2 重写init()方法
@Override
public void init(ServletConfig config) throws ServletException {
doLoadConfig(config.getInitParameter("contextConfigLocation"));
doScanner(contextConfig.getProperty("scanPackage"));
doInstance();
doAutowired();
doInitHandlerMapping();
System.out.println("has been inited");
}
Step3 doLoadConfig()方法
private void doLoadConfig(String contextConfigLocation) {
InputStream is= this.getClass().getClassLoader().getResourceAsStream(contextConfigLocation);
try {
contextConfig.load(is);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is!=null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Step4 doScanner()方法
private void doScanner(String scanPackage) {
URL url= this.getClass().getClassLoader().getResource("/"+scanPackage.replaceAll("\\.","/"));
File classPath=new File(url.getFile());
for (File file : classPath.listFiles()) {
if(file.isDirectory()){
doScanner(scanPackage+"."+file.getName());
}else{
if(!file.getName().endsWith(".class")){continue;}
String className=scanPackage+file.getName().replace(".class","");
classNames.add(className);
}
}
}
Step5 doInstance()方法
private void doInstance() {
if(classNames.isEmpty()){ return;}
try{
for (String className : classNames) {
Class clazz=Class.forName(className);
String name=clazz.getSimpleName();
String beanName=name.substring(0,1).toLowerCase()+name.substring(1);
if(clazz.isAnnotationPresent(GPController.class)){
ioc.put(beanName,clazz.newInstance());
}
else if(clazz.isAnnotationPresent(GPService.class)){
GPService service=(GPService)clazz.getAnnotation(GPService.class);
if(!"".equals(service.value())){
beanName=service.value();
}
Object instance=clazz.newInstance();
ioc.put(beanName,instance);
for (Class i : clazz.getInterfaces()) {
if(ioc.containsKey(i.getName())){
throw new Exception("the beanName has existed");
}
ioc.put(i.getName(),instance);
}
}else{ continue;}
}
}catch (Exception e){
e.printStackTrace();
}
}
Step6 doAutowired()方法
private void doAutowired() {
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(GPAutowired.class)){continue;}
GPAutowired autowired=field.getAnnotation(GPAutowired.class);
String beanName=autowired.value().trim();
if("".equals(beanName)){
beanName=field.getType().getName();
}
field.setAccessible(true);
try {
field.set(entry.getValue(),ioc.get(beanName));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
Step7 doInitHandlerMapping()方法
private void doInitHandlerMapping() {
if(ioc.isEmpty()){return;}
for (Map.Entry<String, Object> entry : ioc.entrySet()) {
Class clazz = entry.getValue().getClass();
if(!clazz.isAnnotationPresent(GPController.class)){continue;}
for (Method method : clazz.getMethods()) {
if(!method.isAnnotationPresent(GPRequestMapping.class)){continue;}
GPRequestMapping requestMapping =method.getAnnotation(GPRequestMapping.class);
String url=("/"+requestMapping.value()).replaceAll("/+","/");
handlerMapping.put(url,method);
System.out.println(url+";"+method);
}
}
}
Step8 doDispatch()方法
private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws IOException, InvocationTargetException, IllegalAccessException {
String url = req.getRequestURI();
String contextPath = req.getContextPath();
url=url.replace(contextPath,"").replaceAll("/+","");
if(!this.handlerMapping.containsKey(url)){
resp.getWriter().write("404 Not Found");
return;
}
Map<String,String[]> params=req.getParameterMap();
Method method = this.handlerMapping.get(url);
String name=method.getDeclaringClass().getSimpleName();
String beanName=name.substring(0,1).toLowerCase()+name.substring(1);
method.invoke(ioc.get(beanName),new Object[]{req,resp,params.get("name")[0]});
}
Reference
www.bilibili.com/video/BV1RJ…