为什么80%的码农都做不了架构师?>>>
一、定义注解
package com.ayo.annotation; import java.lang.annotation.*; /** * 模拟springmvc的@Controller注解 */ @Documented //JAVADOC @Target(ElementType.TYPE) //作用于类上 @Retention(RetentionPolicy.RUNTIME) //限制Annotation的生命周期,我这里自定义的注解显然需要运行时保留 public @interface Controller { /** * 作用于该类上的注解有一个value属性,说白了就是Controller的名称 * @return */ public String value(); }
package com.ayo.annotation; import java.lang.annotation.*; /** * @Qualifier提供依赖注入 */ @Documented @Target(ElementType.FIELD) //作用于字段上,实现注入 @Retention(RetentionPolicy.RUNTIME) public @interface Qualifier { public String value(); }
package com.ayo.annotation; import java.lang.annotation.*; /** * dao层注解 */ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Repository { public String value(); }
package com.ayo.annotation; import java.lang.annotation.*; /** * RequestMapping提供url地址处理映射 */ @Documented @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMapping { public String value(); }
package com.ayo.annotation; import java.lang.annotation.*; /** * 业务层注解 */ @Documented @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Service { public String value(); }
二、写一个DispatcherServlet
package com.ayo.servlet; import com.ayo.annotation.*; import com.ayo.controller.UserController; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; 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.lang.reflect.Field; 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; @WebServlet(name = "dispatcherServlet", urlPatterns = "/*", loadOnStartup = 1, initParams = {@WebInitParam(name = "base-package", value = "com.ayo")}) public class DispatcherServlet extends HttpServlet{ //扫描的基包 private String basePackage = ""; //基包下面所有的带包路径权限定类名 private List<String> packageNames = new ArrayList<String>(); //注解实例化,注解上的名称:实例化对象 private Map<String, Object> instanceMap = new HashMap<String, Object>(); //带包路径的权限定名称:注解上的名称 private Map<String, Object> nameMap = new HashMap<String, Object>(); //url地址和方法的映射关系,springmvc就是方法调用链 private Map<String, Method> urlMethodMap = new HashMap<String, Method>(); //Method和权限定类名映射关系, 主要是为了通过method找到该方法的对象利用反射执行 private Map<Method, String> methodPackageMap = new HashMap<Method, String>(); @Override public void init(ServletConfig config) throws ServletException { basePackage = config.getInitParameter("base-package"); try { //扫描基包得到全部的带包路径权限定名 scanBasePackage(basePackage); //把带有@Controller/@Service/@Repository的类实例化放入map中,key为注解上的名字 instance(packageNames); //Spring IOC注入 springIOC(); //完成URL地址与方法的映射关系 handleUrlMethodMap(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } } /** * 扫描基包 * @param basePackage */ private void scanBasePackage(String basePackage){ //注意为了得到基包下面的URL路径,需要对basePackage包转换,将.替换为/ URL url = this.getClass().getClassLoader().getResource(basePackage.replaceAll("\\.", "/")); File basePackageFile = new File(url.getPath()); System.out.println("scan:" + basePackageFile); File[] childFiles = basePackageFile.listFiles(); for (File file : childFiles){ if (file.isDirectory()){ scanBasePackage(basePackage + "." + file.getName()); }else if (file.isFile()){ packageNames.add(basePackage + "." + file.getName().split("\\.")[0]); } } } /** * 实例化 * @param packageNames * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ private void instance(List<String> packageNames) throws ClassNotFoundException, IllegalAccessException, InstantiationException { if (packageNames.size() < 1){ return; } for (String string : packageNames){ Class<?> c = Class.forName(string); if(c.isAnnotationPresent(Controller.class)){ Controller controller = c.getAnnotation(Controller.class); String controllerName = controller.value(); instanceMap.put(controllerName, c.newInstance()); nameMap.put(string, controllerName); System.out.println("Controller:" + string + ", value:" + controller.value()); }else if (c.isAnnotationPresent(Service.class)){ Service service = c.getAnnotation(Service.class); String serviceName = service.value(); instanceMap.put(serviceName, c.newInstance()); nameMap.put(string, serviceName); System.out.println("Service:" + string + ",value:" + service.value()); }else if (c.isAnnotationPresent(Repository.class)){ Repository repository = c.getAnnotation(Repository.class); String repositoryName = repository.value(); instanceMap.put(repositoryName, c.newInstance()); nameMap.put(string, repositoryName); System.out.println("Repository:" + string + ",value:" + repository.value()); } } } /** * 依赖注入 * @throws IllegalAccessException */ private void springIOC() throws IllegalAccessException { for (Map.Entry<String, Object> entry : instanceMap.entrySet()){ Field[] fields = entry.getValue().getClass().getDeclaredFields(); for (Field field : fields){ if (field.isAnnotationPresent(Qualifier.class)){ String name = field.getAnnotation(Qualifier.class).value(); field.setAccessible(true); field.set(entry.getValue(), instanceMap.get(name)); } } } } /** * url映射处理 * @throws ClassNotFoundException */ private void handleUrlMethodMap() throws ClassNotFoundException { if (packageNames.size() < 1){ return; } for (String string : packageNames){ Class<?> c = Class.forName(string); if (c.isAnnotationPresent(Controller.class)){ Method[] methods = c.getMethods(); StringBuffer baseUrl = new StringBuffer(); if (c.isAnnotationPresent(RequestMapping.class)){ RequestMapping requestMapping = c.getAnnotation(RequestMapping.class); baseUrl.append(requestMapping.value()); } for (Method method : methods){ if (method.isAnnotationPresent(RequestMapping.class)){ RequestMapping requestMapping = method.getAnnotation(RequestMapping.class); baseUrl.append(requestMapping.value()); urlMethodMap.put(baseUrl.toString(), method); methodPackageMap.put(method, string); } } } } } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String uri = req.getRequestURI(); String contextPath = req.getContextPath(); String path = uri.replaceAll(contextPath, ""); Method method = urlMethodMap.get(path); if (method != null){ //通过method拿到controller对象,准备反射执行 String packageName = methodPackageMap.get(method); String controllerName = (String)nameMap.get(packageName); //拿到controller对象 UserController userController = (UserController)instanceMap.get(controllerName); try { method.setAccessible(true); method.invoke(userController); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } }
三、写个controller、service、dao
package com.ayo.controller; import com.ayo.annotation.Controller; import com.ayo.annotation.Qualifier; import com.ayo.annotation.RequestMapping; import com.ayo.service.UserService; @Controller("userController") @RequestMapping("/user") public class UserController { @Qualifier("userServiceImpl") private UserService userService; @RequestMapping("/insert") public void insert(){ userService.insert(); } }
package com.ayo.service; public interface UserService { public void insert(); }
package com.ayo.dao; public interface UserDao { public void insert(); }
参考自:微信公众号--java进阶架构师。