commit 69a800208db6a4c22c3615b2e2501d2d5907e5e7 Author: Yang Haoyu <2241399212@qq.com> Date: Sun Oct 29 22:17:35 2023 +0800 初始化 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..f465add --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/jpa-buddy.xml b/.idea/jpa-buddy.xml new file mode 100644 index 0000000..966d5f5 --- /dev/null +++ b/.idea/jpa-buddy.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..c6eabde --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6d2a6d8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + org.example + test1028 + 1.0-SNAPSHOT + pom + + shiyi-lock + shiyi-mvc + + + + 17 + 17 + UTF-8 + + + + + diff --git a/shiyi-lock/.gitignore b/shiyi-lock/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/shiyi-lock/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/shiyi-lock/pom.xml b/shiyi-lock/pom.xml new file mode 100644 index 0000000..0b46103 --- /dev/null +++ b/shiyi-lock/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.example + test1028 + 1.0-SNAPSHOT + + + shiyi-lock + + + 17 + 17 + UTF-8 + + + diff --git a/shiyi-lock/src/main/java/com/shiyi/lock/SpinLockDemo.java b/shiyi-lock/src/main/java/com/shiyi/lock/SpinLockDemo.java new file mode 100644 index 0000000..93f3652 --- /dev/null +++ b/shiyi-lock/src/main/java/com/shiyi/lock/SpinLockDemo.java @@ -0,0 +1,60 @@ +package com.shiyi.lock; + +/** + * @ClassName : TestApplication + * @Description : + * @Author : YHY + * @Date: 2023-10-28 18:37 + */ + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +/** + * 题目:实现一个自旋锁, + * 自旋锁的好处:循环比较获取没有类似wait的阻塞 + * + * 通过CAS操作完成自旋锁,A线成先进来调用myLock方法自己持有锁5秒钟,B随后进来后发现 + * 当前有线程持有锁,所以只能通过自旋等待,直到A释放锁后B随后抢到 + */ +public class SpinLockDemo +{ + AtomicReference atomicReference = new AtomicReference<>(); + + public void lock() + { + Thread thread = Thread.currentThread(); + System.out.println(Thread.currentThread().getName()+"\t"+"----come in"); + while (!atomicReference.compareAndSet(null,thread)){ + + } + } + + public void unLock() + { + Thread thread = Thread.currentThread(); + atomicReference.compareAndSet(thread,null); + System.out.println(Thread.currentThread().getName()+"\t"+"----task over,unLock...."); + } + + public static void main(String[] args) + { + SpinLockDemo spinLockDemo = new SpinLockDemo(); + + new Thread(() ->{ + spinLockDemo.lock(); + //暂停几秒线程 + try{ TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();} + spinLockDemo.unLock(); + },"A").start(); + + //暂停500毫秒,线程A先于B启动 + try{TimeUnit.MILLISECONDS.sleep(500);} catch (InterruptedException e) {e.printStackTrace();} + + new Thread(() -> { + spinLockDemo.lock(); + + spinLockDemo.unLock(); + },"B").start(); + } +} diff --git a/shiyi-mvc/.gitignore b/shiyi-mvc/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/shiyi-mvc/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/shiyi-mvc/pom.xml b/shiyi-mvc/pom.xml new file mode 100644 index 0000000..375478c --- /dev/null +++ b/shiyi-mvc/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + org.example + test1028 + 1.0-SNAPSHOT + + + shiyi-mvc + + + 17 + 17 + UTF-8 + + + + + javax.servlet + servlet-api + 2.4 + + + + diff --git a/shiyi-mvc/src.main.webapp.WEB_INF/web.xml b/shiyi-mvc/src.main.webapp.WEB_INF/web.xml new file mode 100644 index 0000000..7705001 --- /dev/null +++ b/shiyi-mvc/src.main.webapp.WEB_INF/web.xml @@ -0,0 +1,16 @@ + + + + shiyi-mvc + + DispatcherServlet + com.enjoy.shiyi.servlet.DispatcherServlet + 0 + + + + DispatcherServlet + / + + diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyAutowired.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyAutowired.java new file mode 100644 index 0000000..45ffda5 --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyAutowired.java @@ -0,0 +1,16 @@ +package com.enjoy.shiyi.annaotaion; + +import java.lang.annotation.*; + +/** + * @ClassName : EnjoyAutowired + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:36 + */ +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface EnjoyAutowired { + String value() default ""; +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyController.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyController.java new file mode 100644 index 0000000..0947de3 --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyController.java @@ -0,0 +1,16 @@ +package com.enjoy.shiyi.annaotaion; + +import java.lang.annotation.*; + +/** + * @ClassName : EnjoyController + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:40 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface EnjoyController { + String value() default ""; +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestMapping.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestMapping.java new file mode 100644 index 0000000..981cf1b --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestMapping.java @@ -0,0 +1,16 @@ +package com.enjoy.shiyi.annaotaion; + +import java.lang.annotation.*; + +/** + * @ClassName : EnjoyRequestMapping + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:41 + */ +@Target({ElementType.TYPE,ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface EnjoyRequestMapping { + String value() default ""; +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestParm.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestParm.java new file mode 100644 index 0000000..09d9c00 --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyRequestParm.java @@ -0,0 +1,16 @@ +package com.enjoy.shiyi.annaotaion; + +import java.lang.annotation.*; + +/** + * @ClassName : EnjoyRequestParm + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:43 + */ +@Target({ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface EnjoyRequestParm { + String value() default ""; +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyService.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyService.java new file mode 100644 index 0000000..9b024fb --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/annaotaion/EnjoyService.java @@ -0,0 +1,16 @@ +package com.enjoy.shiyi.annaotaion; + +import java.lang.annotation.*; + +/** + * @ClassName : EnjoyService + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:45 + */ +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface EnjoyService { + String value() default ""; +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/controller/ShiyiController.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/controller/ShiyiController.java new file mode 100644 index 0000000..2f0782d --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/controller/ShiyiController.java @@ -0,0 +1,37 @@ +package com.enjoy.shiyi.controller; + +import com.enjoy.shiyi.annaotaion.EnjoyAutowired; +import com.enjoy.shiyi.annaotaion.EnjoyController; +import com.enjoy.shiyi.annaotaion.EnjoyRequestMapping; +import com.enjoy.shiyi.annaotaion.EnjoyRequestParm; +import com.enjoy.shiyi.service.ShiyiService; + + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * @ClassName : shiyiController控制层 + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:47 + */ +@EnjoyController +@EnjoyRequestMapping("/shiyi") +public class ShiyiController { + @EnjoyAutowired("ShiyiServiceImpl") + private ShiyiService shiyiService; + + public void query(HttpServletRequest request, HttpServletResponse response, @EnjoyRequestParm("name") String name, + @EnjoyRequestParm("age") String age){ + try { + PrintWriter pw = response.getWriter(); + String resule = shiyiService.query(name,age); + pw.write(resule); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/ShiyiService.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/ShiyiService.java new file mode 100644 index 0000000..c3fc54b --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/ShiyiService.java @@ -0,0 +1,11 @@ +package com.enjoy.shiyi.service; + +/** + * @ClassName : ShiyiService + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:48 + */ +public interface ShiyiService { + String query(String name,String age); +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/impl/ShiyiServiceImpl.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/impl/ShiyiServiceImpl.java new file mode 100644 index 0000000..a35cd1a --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/service/impl/ShiyiServiceImpl.java @@ -0,0 +1,20 @@ +package com.enjoy.shiyi.service.impl; + +import com.enjoy.shiyi.annaotaion.EnjoyService; +import com.enjoy.shiyi.service.ShiyiService; + + +/** + * @ClassName : ShiyiServiceImpl + * @Description : + * @Author : YHY + * @Date: 2023-10-28 19:51 + */ +@EnjoyService("ShiyiServiceImpl") +public class ShiyiServiceImpl implements ShiyiService { + @Override + public String query(String name, String age) { + + return "name==="+name+" age==="+age; + } +} diff --git a/shiyi-mvc/src/main/java/com/enjoy/shiyi/servlet/DispatcherServlet.java b/shiyi-mvc/src/main/java/com/enjoy/shiyi/servlet/DispatcherServlet.java new file mode 100644 index 0000000..925703a --- /dev/null +++ b/shiyi-mvc/src/main/java/com/enjoy/shiyi/servlet/DispatcherServlet.java @@ -0,0 +1,240 @@ +package com.enjoy.shiyi.servlet; + +import com.enjoy.shiyi.annaotaion.*; +import com.enjoy.shiyi.controller.ShiyiController; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName : DispatcherServlet + * @Description : + * @Author : YHY + * @Date: 2023-10-28 20:09 + */ +public class DispatcherServlet extends HttpServlet { + + List className = new ArrayList(); + + Map beans = new HashMap(); + Map handlerMap = new HashMap(); + private static final long serialVersionUID = 1L; + + @Override + public void init(ServletConfig config){ + //把所有的bean扫描-----> 扫描所有的class文件 + scanPackage("com.enjoy"); //写到properties + + doInstance();//根据全类名创建bean + + doIoc(); //根据bean进行依赖注入 + + buildURLMapping(); //shiyi/query-----> method 建立映射关系 + + } + + private void scanPackage(String basePackage){ + URL url = this.getClass().getClassLoader().getResource("/"+basePackage.replaceAll("\\.","/")); + String fileStr = url.getFile(); + + File file = new File(fileStr); + + String[] filesStr = file.list(); + + for(String path: filesStr){ + File filePath = new File(fileStr + path); + + if (filePath.isDirectory()){ + scanPackage(basePackage+"."+path); + }else { + //加入LIST + className.add(basePackage+"."+filePath.getName()); //路径+class类名 + } + } + } + + //根据扫描出来的LIST全类名,进行实例化 + private void doInstance(){ + if (className.size() <= 0){ + System.out.println("包扫描失败...."); + return; + } + + + //list的所有class类,对这些类进行实例化 + for (String className:className){ + String cn = className.replace(".class",""); + try { + Class clazz = Class.forName(cn); + if (clazz.isAnnotationPresent(EnjoyController.class)){ + Object instace = clazz.newInstance(); //创建控制类 + + EnjoyRequestMapping requestMapping = clazz.getAnnotation(EnjoyRequestMapping.class); + String rmvalue = requestMapping.value(); + beans.put(rmvalue, instace); + }else if (clazz.isAnnotationPresent(EnjoyService.class)){ + EnjoyService service = clazz.getAnnotation(EnjoyService.class); + Object instace = clazz.newInstance(); + beans.put(service.value(), instace); + }else { + continue; + } + + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + + //把service注入到controller + public void doIoc(){ + if (beans.entrySet().size() <= 0){ + System.out.println("没有一个实例化类"); + } + + for (Map.Entry entry:beans.entrySet()){ + + Object instace = entry.getValue(); + Class clazz = instace.getClass(); + + if (clazz.isAnnotationPresent(EnjoyController.class)){ + Field[] fileds = clazz.getDeclaredFields(); + for (Field filed : fileds) { + if (filed.isAnnotationPresent(EnjoyAutowired.class)){ + EnjoyAutowired auto = filed.getAnnotation(EnjoyAutowired.class); + String key = auto.value(); + //打开权限 才能设值 + filed.setAccessible(true); + try { + //对当前成员变量进行射设值 + filed.set(instace, beans.get(key)); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + }else { + continue; + } + } + }else { + continue; + } + + + } + } + + private void buildURLMapping(){ + if (beans.entrySet().size() <=0 ){ + System.out.println("没有类的实例化------"); + return; + } + + for (Map.Entry entry: beans.entrySet()){ + Object instace = entry.getValue(); + + Class clazz = instace.getClass(); + if (clazz.isAnnotationPresent(EnjoyController.class)){ + EnjoyRequestMapping requestMapping = clazz.getAnnotation(EnjoyRequestMapping.class); + String classPath = requestMapping.value(); + + Method[] methods = clazz.getMethods(); + for (Method method : methods) { + if (method.isAnnotationPresent(EnjoyRequestMapping.class)){ + EnjoyRequestMapping methodMapping = method.getAnnotation(EnjoyRequestMapping.class); + String methodPath = methodMapping.value();//方法的路径 + + handlerMap.put(classPath + methodPath, method); + }else { + continue; + } + } + }else { + continue; + } + } + } + + + @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 { + //获取请求路径 /shiyi-mvc/shiyi/query + String url = req.getRequestURI(); + String context = req.getContextPath(); //shiyi-mvc + String path = url.replace(context, ""); //shiyi/query + + Method method = (Method) handlerMap.get(path); + + //根据key=/shiyi到map去拿 + ShiyiController instance = (ShiyiController) beans.get("/" + path.split("/")[1]); + + Object arg[] = hand(req,resp,method); + try { + method.invoke(instance,arg); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + //这里不用策略模式,VIP才有策略模式 + private static Object[] hand(HttpServletRequest request, HttpServletResponse response,Method method){ + //拿到当前待执行方法有哪些参数 + Class[] paramClazzs = method.getParameterTypes(); + //根据参数的个数,new 一个参数的数组,讲方法里的所有参数赋值到args来 + Object[] args = new Object[paramClazzs.length]; + + int args_i = 0; + int index = 0; + for (Class paramClazz : paramClazzs) { + if (ServletRequest.class.isAssignableFrom(paramClazz)){ + args[args_i++] = request; + } + if (ServletResponse.class.isAssignableFrom(paramClazz)){ + args[args_i++] = response; + } + //从0-3判断有没有RequestParam注解,很明显paramClazz为0和1时,不是 + //当为2时为@RequestParam,需要解析 + //[@com.enjoy.shiyi.annaotaion.EnjoyRequestMapping(value=name)] + Annotation[] paramAns = method.getParameterAnnotations()[index]; + if (paramAns.length > 0){ + for (Annotation paramAn : paramAns) { + if (EnjoyRequestParm.class.isAssignableFrom(paramAn.getClass())){ + EnjoyRequestParm rp = (EnjoyRequestParm) paramAn; + //找到注解里的name和age + args[args_i++] = request.getParameter(rp.value()); + } + } + } + index++; + } + return args; + } + +}