├── .factorypath ├── .gitignore ├── README.md ├── pom.xml ├── src └── main │ ├── java │ └── com │ │ └── dean │ │ └── framework │ │ ├── DkDispatcherServlet.java │ │ ├── core │ │ └── annotation │ │ │ ├── DkAutowired.java │ │ │ ├── DkController.java │ │ │ ├── DkRequestMapping.java │ │ │ ├── DkRequestParam.java │ │ │ └── DkService.java │ │ └── sample │ │ ├── GeneralAction.java │ │ ├── ServiceA.java │ │ ├── ServiceAImpl.java │ │ ├── ServiceB.java │ │ ├── ServiceBImpl.java │ │ ├── UserAction.java │ │ ├── UserService.java │ │ └── UserServiceImpl.java │ ├── resources │ ├── application.properties │ └── spring架构整体流程.png │ └── webapp │ └── WEB-INF │ └── web.xml └── static └── img └── service-call.png /.factorypath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | .apt_generated 5 | .classpath 6 | .factorypath 7 | .project 8 | .settings 9 | .springBeans 10 | .sts4-cache 11 | 12 | .idea 13 | *.iws 14 | *.iml 15 | *.ipr 16 | 17 | /nbproject/private/ 18 | /nbbuild/ 19 | /dist/ 20 | /nbdist/ 21 | /.nb-gradle/ 22 | /build/ 23 | ======= 24 | # Maven # 25 | target/ 26 | 27 | # IDEA # 28 | .idea/ 29 | *.iml 30 | 31 | # Eclipse # 32 | .settings/ 33 | .classpath 34 | .project 35 | 36 | # jrebel # 37 | src/main/resources/rebel.xml 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 简单设计实践spring框架(手写spring) 2 | 3 | `@author DeanKano` 4 | 5 | ## 核心流程: 6 | 7 | 8 | ##### Step1 配置依赖(仅仅依赖servlet-api包) 9 | 10 | ```asp 11 | 12 | 13 | javax.servlet 14 | servlet-api 15 | 2.4 16 | 17 | 18 | ``` 19 | 20 | ##### Step2 定义一个核心控制器 21 | 22 | > DkDispatcherServlet extends HttpServlet {...} 23 | 24 | `在web.xml配置核心控制器` 25 | 26 | ```asp 27 | 28 | 29 | 30 | dkDispatcher 31 | com.dean.framework.DkDispatcherServlet 32 | 33 | contextConfigLocation 34 | classpath:application.properties 35 | 36 | 1 37 | 38 | 39 | dkDispatcher 40 | /* 41 | 42 | 43 | 44 | ``` 45 | 46 | 47 | ##### Step3 自定义一些类spring的注解 48 | 49 | > @DkController 50 | 51 | > @DkService 52 | 53 | > @DkAutowired 54 | 55 | > @DkRequestMapping 56 | 57 | > @DkRequestParam 58 | 59 | ##### Step4 配置容器启动时的初始化 60 | 61 | > 1 加载配置文件 doLoadConfig(..) 62 | 63 | > 2 扫描配置包路径 doScanner(..) 64 | 65 | > 3 反射实例化加载到IOC容器中 doInstance(); 66 | 67 | > 4 DI依赖注入,针对IOC容器中加载到的类,自动对需要赋值的属性进行初始化操作 doAutowired(); 68 | 69 | > 5 初始化HandlerMapping initHandlerMapping(); 70 | 71 | ##### Step5 执行请求,请求分发 72 | > doDispatcher(req, resp); 73 | 74 | ##### Step6 启动 75 | 76 | ```asp 77 | 78 | 一 直接运行maven 插件 jetty:run 79 | 80 | 二 命令行启动,在cmd窗口执行: 81 | 82 | `$mvn jetty:run` 83 | 84 | ``` 85 | 86 | ##### Step7 验证功能 87 | 88 | 启动日志: 89 | 90 | ```asp 91 | ... 92 | [INFO] Starting jetty 6.1.7 ... 93 | [INFO] jetty-6.1.7 94 | [INFO] No Transaction manager found - if your webapp requires one, please configure one. 95 | Mapping: [/sample/query.do] ==>public void com.dean.framework.sample.UserAction.query(java.lang.String,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 96 | Mapping: [/sample/add.do] ==>public void com.dean.framework.sample.UserAction.addUser(java.lang.String,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 97 | Mapping: [/sample/remove.do] ==>public void com.dean.framework.sample.UserAction.removeUser(java.lang.String,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) 98 | [INFO] Started SelectChannelConnector@0.0.0.0:8080 99 | [INFO] Started Jetty Server 100 | 101 | ``` 102 | 103 | 请求示例: 104 | 105 | `http://localhost:8080/sample/query.do?name=Tom` 106 | 107 | 108 | ## 一 针对循环依赖问题的验证: 109 | 110 | ```asp 111 | ServiceA跟ServiceB相互依赖问题: 112 | 113 | ServiceA 114 | -serviceB 115 | 116 | ServiceB 117 | -ServiceA 118 | ``` 119 | 120 | 121 | 122 | 123 | ## 唠唠嗑 124 | 125 | | 联系我 | 下午茶(支付宝) | 下午茶(微信)| 126 | | :------: | :------: | :------: | 127 | | | | | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | rangers-framewor-springk 8 | com.dean.framework 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 13 | 1.8 14 | 1.8 15 | 1.8 16 | 1.8 17 | 18 | 19 | 20 | 21 | javax.servlet 22 | servlet-api 23 | 2.4 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.mortbay.jetty 32 | maven-jetty-plugin 33 | 6.1.7 34 | 35 | 36 | 37 | 8080 38 | 30000 39 | 40 | 41 | ${project.basedir}/src/main/webapp 42 | / 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/DkDispatcherServlet.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework; 2 | 3 | import com.dean.framework.core.annotation.*; 4 | 5 | import javax.servlet.ServletConfig; 6 | import javax.servlet.ServletException; 7 | import javax.servlet.http.HttpServlet; 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.io.InputStream; 13 | import java.lang.annotation.Annotation; 14 | import java.lang.reflect.Field; 15 | import java.lang.reflect.InvocationTargetException; 16 | import java.lang.reflect.Method; 17 | import java.net.URL; 18 | import java.util.*; 19 | import java.util.regex.Matcher; 20 | import java.util.regex.Pattern; 21 | 22 | /** 23 | * 24 | * @author fuhw/Dean 25 | * @date 2018-10-29 26 | */ 27 | public class DkDispatcherServlet extends HttpServlet { 28 | 29 | private static final String EMPTY_STRING = ""; 30 | private static final String SLASH_STRING = "/"; 31 | private static final String SPOT_STRING = "."; 32 | 33 | private static Properties contextConfig = new Properties(); 34 | private static List classNames = new ArrayList<>(); 35 | private static Map ioc = new HashMap<>(); 36 | private static List handlerMapping = new ArrayList<>(); 37 | 38 | @Override 39 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 40 | this.doPost(req, resp); 41 | 42 | } 43 | 44 | @Override 45 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 46 | try { 47 | doDispatcher(req, resp); 48 | } catch (Exception e) { 49 | resp.getWriter().write("500 SERVER ERROR"); 50 | e.printStackTrace(); 51 | } 52 | } 53 | 54 | private void doDispatcher(HttpServletRequest req, HttpServletResponse resp) throws InvocationTargetException, IllegalAccessException, IOException { 55 | Handler handler = retrieveHandler(req); 56 | if (handler == null) { 57 | resp.getWriter().write("404 NOT FOUND"); 58 | return; 59 | } 60 | 61 | Object[] paramValues = new Object[handler.method.getParameterTypes().length]; 62 | // String[]可能多个参数,例如:?name=tom&name=jaine 63 | Map reqParams = req.getParameterMap(); 64 | for (Map.Entry stringEntry : reqParams.entrySet()) { 65 | String paramName = stringEntry.getKey(); 66 | if (!handler.paramsIndexMapping.keySet().contains(paramName)) { 67 | continue; 68 | } 69 | 70 | int paramIndex = handler.paramsIndexMapping.get(paramName); 71 | paramValues[paramIndex] = Arrays.toString(stringEntry.getValue()).replaceAll("\\[|\\]", EMPTY_STRING); 72 | } 73 | 74 | int respIndex = handler.paramsIndexMapping.get(HttpServletResponse.class.getName()); 75 | int reqIndex = handler.paramsIndexMapping.get(HttpServletRequest.class.getName()); 76 | paramValues[reqIndex] = req; 77 | paramValues[respIndex] = resp; 78 | 79 | handler.method.invoke(handler.controller, paramValues); 80 | 81 | } 82 | 83 | private Handler retrieveHandler(HttpServletRequest req) { 84 | String requestURI = req.getRequestURI(); 85 | requestURI = requestURI.replace(req.getContextPath(), EMPTY_STRING); 86 | for (Handler handler : handlerMapping) { 87 | Matcher matcher = handler.pattern.matcher(requestURI); 88 | if (!matcher.matches()) { 89 | continue; 90 | } 91 | return handler; 92 | } 93 | return null; 94 | } 95 | 96 | @Override 97 | public void init(ServletConfig config) throws ServletException { 98 | 99 | // 1 加载配置文件 100 | doLoadConfig(config.getInitParameter("contextConfigLocation")); 101 | 102 | // 2 扫描配置包路径 103 | doScanner(contextConfig.getProperty("scanPackage")); 104 | 105 | // 3 反射实例化加载到IOC容器中 106 | doInstance(); 107 | 108 | // 4 DI依赖注入,针对IOC容器中加载到的类,自动对需要赋值的属性进行初始化操作 109 | doAutowired(); 110 | 111 | // 5 初始化HandlerMapping 112 | initHandlerMapping(); 113 | 114 | } 115 | 116 | private void initHandlerMapping() { 117 | if (ioc.isEmpty()) return; 118 | for (Map.Entry entry : ioc.entrySet()) { 119 | Class clazz = entry.getValue().getClass(); 120 | if (!clazz.isAnnotationPresent(DkController.class)) { 121 | continue; 122 | } 123 | String baseUrl = EMPTY_STRING; 124 | if (clazz.isAnnotationPresent(DkRequestMapping.class)) { 125 | DkRequestMapping dkRequestMapping = clazz.getAnnotation(DkRequestMapping.class); 126 | baseUrl = dkRequestMapping.value(); 127 | } 128 | 129 | for (Method method : clazz.getMethods()) { 130 | if (!method.isAnnotationPresent(DkRequestMapping.class)) { 131 | continue; 132 | } 133 | DkRequestMapping dkRequestMapping = method.getAnnotation(DkRequestMapping.class); 134 | String regexUrl = (SLASH_STRING + baseUrl + dkRequestMapping.value()).replaceAll("/+", SLASH_STRING); 135 | Pattern pattern = Pattern.compile(regexUrl); 136 | handlerMapping.add(new Handler(method, entry.getValue(), pattern)); 137 | 138 | System.out.println("Mapping: [" + regexUrl + "] ==>" + method); 139 | } 140 | } 141 | } 142 | 143 | private void doAutowired() { 144 | if (ioc.isEmpty()) return; 145 | for (Map.Entry entry : ioc.entrySet()) { 146 | Field[] declaredFields = entry.getValue().getClass().getDeclaredFields(); 147 | for (Field declaredField : declaredFields) { 148 | if (!declaredField.isAnnotationPresent(DkAutowired.class)) { 149 | continue; 150 | } 151 | String beanName = getFirstLower(declaredField.getType().getName()); 152 | DkAutowired annotation = declaredField.getAnnotation(DkAutowired.class); 153 | if (!EMPTY_STRING.equals(annotation.value())) { 154 | beanName = annotation.value(); 155 | } 156 | try { 157 | declaredField.setAccessible(true); 158 | declaredField.set(entry.getValue(), ioc.get(beanName)); 159 | } catch (IllegalAccessException e) { 160 | e.printStackTrace(); 161 | continue; 162 | } 163 | } 164 | 165 | } 166 | } 167 | 168 | private void doInstance() { 169 | if (classNames.isEmpty()) return; 170 | 171 | for (String className : classNames) { 172 | 173 | try { 174 | Class clazz = Class.forName(className); 175 | if (clazz.isInterface()) continue; 176 | // 针对指定扫描到的包进行实例化 177 | 178 | // 默认bean名称是类名的首字母小写 179 | String beanName = getFirstLower(clazz.getName()); 180 | Object newInstance = clazz.newInstance(); 181 | if (clazz.isAnnotationPresent(DkController.class)) { 182 | // 指定了bean名称 183 | DkController dkController = clazz.getAnnotation(DkController.class); 184 | if (!EMPTY_STRING.equals(dkController.value())) { 185 | beanName = dkController.value(); 186 | } 187 | 188 | } else if (clazz.isAnnotationPresent(DkService.class)) { 189 | // 指定bean名称 190 | DkService dkService = clazz.getAnnotation(DkService.class); 191 | if (!EMPTY_STRING.equals(dkService.value())) { 192 | beanName = dkService.value(); 193 | } 194 | 195 | // 针对接口的,bean名称用接口的名称 196 | Class[] interfaces = clazz.getInterfaces(); 197 | if (interfaces.length == 1) { 198 | for (Class anInterface : interfaces) { 199 | beanName = getFirstLower(anInterface.getName()); 200 | } 201 | } else if (interfaces.length > 1) { 202 | // TODO 多接口 203 | } 204 | 205 | } else { 206 | continue; 207 | } 208 | ioc.put(beanName, newInstance); 209 | 210 | } catch (Exception e) { 211 | e.printStackTrace(); 212 | } 213 | 214 | } 215 | } 216 | 217 | private String getFirstLower(String className) { 218 | String[] strings = className.split("\\."); 219 | String beanName = strings[strings.length - 1]; 220 | char[] chars = beanName.toCharArray(); 221 | chars[0] += 32; 222 | return String.valueOf(chars); 223 | } 224 | 225 | private void doScanner(String scanPackage) { 226 | URL url = this.getClass().getClassLoader().getResource( 227 | SLASH_STRING + scanPackage.replaceAll("\\.", SLASH_STRING)); 228 | if (url == null) return; 229 | File classDir = new File(url.getFile()); 230 | for (File file : classDir.listFiles()) { 231 | if (file.isDirectory()) { 232 | doScanner(scanPackage + SPOT_STRING + file.getName()); 233 | } else { 234 | String className = scanPackage + SPOT_STRING + 235 | file.getName().replace(".class", EMPTY_STRING); 236 | classNames.add(className); 237 | } 238 | } 239 | } 240 | 241 | private void doLoadConfig(String contextConfigLocation) { 242 | contextConfigLocation = contextConfigLocation.replace("classpath:", EMPTY_STRING); 243 | try (InputStream resourceAsStream = this.getClass().getClassLoader() 244 | .getResourceAsStream(contextConfigLocation)) { 245 | contextConfig.load(resourceAsStream); 246 | } catch (Exception e) { 247 | e.printStackTrace(); 248 | } 249 | } 250 | 251 | 252 | static class Handler { 253 | private Method method; 254 | private Object controller; 255 | private Pattern pattern; 256 | private Map paramsIndexMapping; 257 | 258 | public Handler(Method method, Object controller, Pattern pattern) { 259 | this.method = method; 260 | this.controller = controller; 261 | this.pattern = pattern; 262 | this.paramsIndexMapping = new HashMap<>(); 263 | this.putParamsIndexMapping(method); 264 | } 265 | 266 | private void putParamsIndexMapping(Method method) { 267 | Annotation[][] parameterAnnotations = method.getParameterAnnotations(); 268 | for (int i = 0; i < parameterAnnotations.length; i++) { 269 | for (Annotation parameterAnnotation : parameterAnnotations[i]) { 270 | if (parameterAnnotation instanceof DkRequestParam) { 271 | String paramName = ((DkRequestParam) parameterAnnotation).value(); 272 | paramsIndexMapping.put(paramName, i); 273 | } 274 | } 275 | } 276 | 277 | // 提取request和response 278 | Class[] parameterTypes = method.getParameterTypes(); 279 | for (int i = 0; i < parameterTypes.length; i++) { 280 | Class parameterType = parameterTypes[i]; 281 | if (parameterType.equals(HttpServletRequest.class) 282 | || parameterType.equals(HttpServletResponse.class)) { 283 | paramsIndexMapping.put(parameterType.getName(), i); 284 | } 285 | } 286 | 287 | } 288 | 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/core/annotation/DkAutowired.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author fuhw/Dean 7 | * @date 2018-10-29 8 | */ 9 | @Target({ElementType.TYPE, ElementType.FIELD}) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface DkAutowired { 13 | 14 | String value() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/core/annotation/DkController.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 7 | * @author fuhw/Dean 8 | * @date 2018-10-29 9 | */ 10 | @Target(ElementType.TYPE) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface DkController { 14 | 15 | String value() default ""; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/core/annotation/DkRequestMapping.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 7 | * @author fuhw/Dean 8 | * @date 2018-10-29 9 | */ 10 | @Target({ElementType.TYPE,ElementType.METHOD}) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface DkRequestMapping { 14 | 15 | String value() default ""; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/core/annotation/DkRequestParam.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 7 | * @author fuhw/Dean 8 | * @date 2018-10-29 9 | */ 10 | @Target({ElementType.PARAMETER}) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Documented 13 | public @interface DkRequestParam { 14 | 15 | String value() default ""; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/core/annotation/DkService.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.core.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author fuhw/Dean 7 | * @date 2018-10-29 8 | */ 9 | @Target({ElementType.TYPE}) 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Documented 12 | public @interface DkService { 13 | 14 | String value() default ""; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/GeneralAction.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | 10 | /** 11 | * 普通 12 | * 13 | * @author fuhw/Dean 14 | * @date 2018-10-23 15 | */ 16 | public class GeneralAction extends HttpServlet { 17 | 18 | @Override 19 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 20 | System.out.println("处理Get请求。。。。。"); 21 | PrintWriter out = resp.getWriter(); 22 | out.println("Hello Servlet-Get"); 23 | } 24 | 25 | @Override 26 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 27 | System.out.println("处理Post请求。。。。。"); 28 | PrintWriter out = resp.getWriter(); 29 | out.println("Hello Servlet-Post"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/ServiceA.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | /** 4 | * @author fuhw/Dean 5 | * @date 2018-10-23 6 | */ 7 | public interface ServiceA { 8 | 9 | String getName(); 10 | 11 | String print(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/ServiceAImpl.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | import com.dean.framework.core.annotation.DkAutowired; 4 | import com.dean.framework.core.annotation.DkService; 5 | 6 | /** 7 | * TODO 8 | * 9 | * @author fuhw/Dean 10 | * @date 2020-05-18 11 | */ 12 | @DkService 13 | public class ServiceAImpl implements ServiceA { 14 | 15 | @DkAutowired 16 | private ServiceB serviceB; 17 | 18 | @Override 19 | public String getName() { 20 | return "ServiceA"; 21 | } 22 | 23 | @Override 24 | public String print() { 25 | return getName() + ": Hello" + serviceB.getName(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/ServiceB.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | /** 4 | * @author fuhw/Dean 5 | * @date 2018-10-23 6 | */ 7 | public interface ServiceB { 8 | 9 | String getName(); 10 | 11 | String print(); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/ServiceBImpl.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | import com.dean.framework.core.annotation.DkAutowired; 4 | import com.dean.framework.core.annotation.DkService; 5 | 6 | /** 7 | * 8 | * @author fuhw/Dean 9 | * @date 2020-05-18 10 | */ 11 | @DkService 12 | public class ServiceBImpl implements ServiceB { 13 | 14 | @DkAutowired 15 | private ServiceA serviceA; 16 | 17 | @Override 18 | public String getName() { 19 | return "ServiceB"; 20 | } 21 | 22 | @Override 23 | public String print() { 24 | return getName() + ": Hello" + serviceA.getName(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/UserAction.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | import com.dean.framework.core.annotation.DkAutowired; 4 | import com.dean.framework.core.annotation.DkController; 5 | import com.dean.framework.core.annotation.DkRequestMapping; 6 | import com.dean.framework.core.annotation.DkRequestParam; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import java.io.IOException; 11 | 12 | /** 13 | * @author fuhw/Dean 14 | * @date 2018-10-23 15 | */ 16 | @DkController 17 | @DkRequestMapping("/sample") 18 | public class UserAction { 19 | 20 | @DkAutowired 21 | private UserService userService; 22 | 23 | @DkAutowired 24 | private ServiceA serviceA; 25 | 26 | @DkRequestMapping("/print.do") 27 | public void printA( 28 | HttpServletRequest req, HttpServletResponse resp) { 29 | try { 30 | resp.getWriter().write(serviceA.print()); 31 | } catch (IOException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | 36 | @DkRequestMapping("/add.do") 37 | public void addUser(@DkRequestParam("name") String name, 38 | HttpServletRequest req, HttpServletResponse resp) { 39 | try { 40 | resp.getWriter().write(userService.add(name)); 41 | } catch (IOException e) { 42 | e.printStackTrace(); 43 | } 44 | } 45 | 46 | @DkRequestMapping("/remove.do") 47 | public void removeUser(@DkRequestParam("name") String name, 48 | HttpServletRequest req, HttpServletResponse resp) { 49 | try { 50 | resp.getWriter().write(userService.remove(name)); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | @DkRequestMapping("/query.do") 57 | public void query(@DkRequestParam("name") String name, 58 | HttpServletRequest req, HttpServletResponse resp) { 59 | try { 60 | resp.getWriter().write(userService.query(name)); 61 | } catch (IOException e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/UserService.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | /** 4 | * @author fuhw/Dean 5 | * @date 2018-10-23 6 | */ 7 | public interface UserService { 8 | 9 | String add(String name); 10 | 11 | String remove(String name); 12 | 13 | String query(String name); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/dean/framework/sample/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.dean.framework.sample; 2 | 3 | import com.dean.framework.core.annotation.DkService; 4 | 5 | /** 6 | * @author fuhw/Dean 7 | * @date 2018-10-23 8 | */ 9 | @DkService 10 | public class UserServiceImpl implements UserService { 11 | 12 | public String add(String name) { 13 | return "You add user : name= " + name; 14 | } 15 | 16 | public String remove(String name) { 17 | return "You remove user : name=" + name; 18 | } 19 | 20 | public String query(String name) { 21 | return "You query user : name=" + name; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | scanPackage=com.dean.framework.sample -------------------------------------------------------------------------------- /src/main/resources/spring架构整体流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dean-coding/rangers-framework-spring/2803005479674b7badfef69f3c5f1704d90c4a11/src/main/resources/spring架构整体流程.png -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | rangers-framework 9 | 10 | 11 | 12 | dkDispatcher 13 | com.dean.framework.DkDispatcherServlet 14 | 15 | contextConfigLocation 16 | classpath:application.properties 17 | 18 | 1 19 | 20 | 21 | dkDispatcher 22 | /* 23 | 24 | 25 | 26 | 27 | general 28 | com.dean.framework.sample.GeneralAction 29 | 30 | 31 | general 32 | /general 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /static/img/service-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dean-coding/rangers-framework-spring/2803005479674b7badfef69f3c5f1704d90c4a11/static/img/service-call.png --------------------------------------------------------------------------------