对于Service的自动注入
一. 前言
在前上一章教程中,我们实现了简单的Web框架。本章将在上一章的基础上,进一步扩展程序。注:
1.本文针对初学Java的同学训练学习思路,请不要太纠结于细节问题。2.本文旨在达到抛砖引玉的效果,希望大家扩展本例子,以学到更多知识的精髓。学习本章需要准备的知识:
1.读完本系列教程的前面章节。二. 步入正题
话不多说,大家自己理解,下面步入正题:我们来实现Service的自动注入。
我们希望把Servcie获得的代码做如下修改:修改前:修改后:
这样减少了框架对业务代码的侵入。
首先修改PersonController如下:1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 @Controller 7 public class PersonController { 8 9 @Autowired10 public PersonService personService;11 12 @Request(path="/person.do")13 public String query(@Parameter(name="personid")String personId) {14 15 Person personResult = personService.getPerson(personId);16 17 StringBuffer result = new StringBuffer();18 result.append("id:"+personResult.id);19 result.append("username:"+personResult.username);20 result.append("password:"+personResult.passwd);21 22 return result.toString();23 }24 25 }
制作如下两个注解:
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 @Target(value = { ElementType.FIELD }) 7 @Retention(value = RetentionPolicy.RUNTIME) 8 public @interface Autowired { 9 10 }
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 @Target(value = { ElementType.TYPE }) 7 @Retention(value = RetentionPolicy.RUNTIME) 8 public @interface Service { 9 10 }
修改PersonService代码如下:
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 @Service 7 public class PersonService { 8 9 @Autowired10 public PersonDao personDao;11 12 public Person getPerson(String personid) {13 14 15 Person person = personDao.getPersonById(personid);16 17 return person;18 }19 }
修改DispacherServlet代码如下:
1 /** 2 * 3 * @author http://www.java123.vip 4 * 5 */ 6 public class DispacherServlet extends HttpServlet{ 7 8 private MapcontrollerMap = new HashMap (); 9 10 public DispacherServlet() { 11 12 String controllerPackage = "vip.java123.fileview.app.web"; 13 String servicePackage = "vip.java123.fileview.app.service"; 14 15 MyContainer container = MyContainer.getInstance(); 16 17 try { 18 // load all service 19 // 扫描service包下面的所有类,创建实例并对@Autowired注解属性注入实例 20 Class[] serviceClasses = ClassScaner.getClasses(servicePackage); 21 for(int i = 0; i < serviceClasses.length; i ++) { 22 Class serviceClass = serviceClasses[i]; 23 24 // 生成实例 25 Object serviceObj = container.getObject(serviceClass); 26 27 // 处理@Autowired注解属性 28 Field[] fields = serviceClass.getFields(); 29 for(int j = 0; j < fields.length; j++) { 30 Field field = fields[j]; 31 if(field.getAnnotation(Autowired.class) != null) { 32 Class autowiredClass = field.getType(); 33 34 // 对@Autowired注入实例 35 Object autowiredObj = container.getObject(autowiredClass); 36 field.set(serviceObj, autowiredObj); 37 } 38 } 39 40 } 41 42 43 // load all controller 44 // 扫描controller包下面的所有类,并加载包含注解@Controller的类 45 Class[] controllerClasses = ClassScaner.getClasses(controllerPackage); 46 for(int i = 0; i < controllerClasses.length; i ++) { 47 Class controllerClass = controllerClasses[i]; 48 49 // 判断是否含有注解@Controller 50 if(controllerClass.getAnnotation(Controller.class) != null) { 51 52 // 生成新的Controller实例 53 Object controllerObj = controllerClass.newInstance(); 54 55 // 处理@Autowired注解属性 56 Field[] fields = controllerClass.getFields(); 57 for(int j = 0; j < fields.length; j++) { 58 Field field = fields[j]; 59 if(field.getAnnotation(Autowired.class) != null) { 60 Class autowiredClass = field.getType(); 61 // 对@Autowired注入实例 62 Object autowiredObj = container.getObject(autowiredClass); 63 field.set(controllerObj, autowiredObj); 64 } 65 } 66 67 // 扫描所有的方法 68 Method[] methods = controllerClass.getMethods(); 69 for(int j = 0; j < methods.length; j ++) { 70 Method method = methods[j]; 71 72 // 加载含有@Request注解的方法 73 Request requestAnnotation = method.getAnnotation(Request.class); 74 if(requestAnnotation != null) { 75 76 // 注解声明的请求路径 77 String path = requestAnnotation.path(); 78 79 // 做一个invoker,以便请求过来时调用 80 ControllerInvoker invoker = new ControllerInvoker(); 81 invoker.path = path; 82 invoker.obj = controllerObj; 83 invoker.method = method; 84 85 // 处理@Parameter注解 86 List parameterNameList = new ArrayList (); 87 Annotation[][] annotations = method.getParameterAnnotations(); 88 for(int k = 0; k < annotations.length; k ++) { 89 if(annotations[k].length > 0) { 90 Parameter parameterAnnotaion = (Parameter)annotations[k][0]; 91 String parameterName = parameterAnnotaion.name(); 92 parameterNameList.add(parameterName); 93 } 94 } 95 invoker.paramNames = new String[parameterNameList.size()]; 96 for(int m = 0; m < parameterNameList.size(); m ++) { 97 invoker.paramNames[m] = parameterNameList.get(m); 98 } 99 100 // 将做好的invoker放入Map中,key为请求路径101 System.out.println("load controller:"+path);102 controllerMap.put(path, invoker);103 }104 }105 }106 }107 108 } catch (ClassNotFoundException e) {109 e.printStackTrace();110 } catch (IOException e) {111 e.printStackTrace();112 } catch (InstantiationException e) {113 e.printStackTrace();114 } catch (IllegalAccessException e) {115 e.printStackTrace();116 }117 118 }119 120 121 /**122 * 处理Get请求123 */124 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {125 // 获得请求路径126 String contextPath = request.getContextPath();127 String requestPath = request.getRequestURI();128 String path = requestPath.replace(contextPath, "");129 130 System.out.println("request:"+path);131 132 // 根据请求路径获得做好的invoker133 ControllerInvoker invoker = controllerMap.get(path);134 135 if(invoker != null) {136 // 根据请求的参数值设置invoker137 invoker.paramValues = new String[invoker.paramNames.length];138 for(int i = 0; i < invoker.paramNames.length; i ++) {139 invoker.paramValues[i] = request.getParameter(invoker.paramNames[i]);140 }141 142 // 调用invoker,并将结果写到response中143 String result = invoker.invokMethod();144 response.getWriter().println(result);145 }146 }147 148 }
三. 测试
启动服务器:
向服务器请求person.html文件,在浏览器端输入1,点query按钮:
显示查询结果:
完整程序请大家从[]下载
如有问题,大家来我的网站进行提问。
版权声明:本教程版权归java123.vip所有,禁止任何形式的转载与引用。