DispathcerServlet Spring Web 简易框架
目录
DispathcerServlet Spring Web 简易框架
-
准备 applicationContext.xml 对应 bean
1 2 3 4 5 6 7 8 9 10 11 12
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="fruitDao" class="com.test.dao.FruitDao"/> <bean id="fruitService" class="com.test.service.impl.FruitServiceImpl"> <property name="fruitDao" ref="fruitDao"/> </bean> <bean id="fruit" class="com.test.controller.FruitController"> <property name="fruitService" ref="fruitService"/> </bean> </beans>
-
通过实现 ServletContextListener 监听器接口,并重写 contextInitialized 方法获取 BeanFactory 对象放入 ServletContext 域中
1 2 3 4 5
// 创建 BeanFactory 对象 BeanFactory beanFactory = new ClassPathXmlApplicationContext(); ServletContext application = ServletContextEvent.getServletContext(); // 放入应用域总中 application.setAttribute("beanFactory", beanFactory);
-
新建 BeanFactory 接口,并创建 ClassPathXmlApplicationContext 实现类通过 applicationContext.xml 文件获取相对应的 bean
1 2 3 4 5 6
// 转化 path 为流 InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); // 获取 document 对象 DocumentBuildFactory dbf = DocumentBuildFactory.newInstance(); DocumentBuild db = dbf.newDocumentBuild(); Document doc = db.parse(is);
-
遍历节点找到元素节点加入到 beanMap 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 获取 nodeList NodeList nodeList = doc.getDocumentElement(); // 将 bean 节点放入 beanMap for (int i = 0; i < nodeList.getLength(); i++) { Node node = NodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; String id = element.getAttribute("id"); String clazz = element.getAttribute("class"); // 反射获取 class Object beanObj = Class.forName(clazz).newInstance(); beanMap.put(id, beanObj); } }
-
再次循环进行依赖注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { // 获取子节点 property Element baseBean = (Element) node; String baseId = baseBean.getAttribute("id"); NodeList childNodes = node.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node property = childNodes.item(j); if (property.getNodeType() == Node.ELEMENT_NODE) { Element propertyEle = (Element) property; String name = propertyEle.getAttribute("name"); String ref = propertyEle.getAttribute("ref"); Object baseObj = beanMap.get(baseId); Object refObj = beanMap.get(ref); // 反射获取成员变量 Field dependency = baseObj.getClass().getDeclaredField(name); dependency.setAccessible(true); // 设置依赖 dependency.set(baseObj, refObj); } } } }
-
在 DispatcherServlet 类中继承 HttpServlet 并在 init() 方法中从 ServletContext 获取 beanFactory
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
public class DispatcherServlet implements HttpServlet { public BeanFactory beanFactory; @Override public void init () throw ServletException { ServletContext application = this.getServletContext(); Object beanFactoryObj = application.getAttribute("beanFactory"); if (beanFactoryObj != null) { beanFactory = (BeanFactory) beanFactory; }else { throw new RuntimeException("Ioc 容器获取失败!"); } } }
-
在 DispatcherServlet service 方法中利用请求中的 operate 反射获取调用方法,并通过 url 地址从 beanFactory 获取操作的 Controller
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
public void service (HttpServletRequest request, HttpServletResponse response) throw ServletException, IOException, IllegalAccessException, InvocationTargetException { request.setCharacterEncoding("UTF-8"); // 获取路径并分割 String uri = request.getServletPath().substring(1); // /fruit?operate=add -> fruit?.. String beanName = uri.contains("?") ? uri.substring(0, uri.indexOf("?") : uri); String operate = request.getParameter("operate"); if (operate == null || "".equals(operate)) { operate = "index"; } // 通过 beanName 获取对应实体类 Object beanObj = Class.forName(beanName).newInstance(); // 获取对应 operate Method[] methods = beanObj.getClass().getDeclaredMethods(); for (Method method : methods) { String methodName = method.getName(); if (operate.equals(methodName)) { // 获取参数 Parameter[] parameter = method.getParameters(); Object[] paramVal = new Object[parameter.length]; for (int i = 0; i < parameters.length; i++) { if (parameters[i].getType().getName().contains("request")) { paramVal[i] = request; } else if (parameters[i].getType().getName().contains("response")) { paramVal[i] = response; } } method.setAccessible(true); method.invoke(beanObj, paramVal); } } }
-
完整代码
-
Listener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
public class MyServletContextListener implements ServletContextListener () { @Override public void contextInitialized (ServletContextEvent servletContextEvent) { // 创建 BeanFactory 对象 BeanFactory beanFactory = new ClassPathXmlApplicationContext(); ServletContext application = ServletContextEvent.getServletContext(); // 放入应用域总中 application.setAttribute("beanFactory", beanFactory); } @Override public void contextDestroyed (ServletContextEvent servletContextEvent) { } }
-
ClassPathXmlApplicationContext 实现
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
public interface BeanFactory { Object getBean(String id); } public class ClassPathXmlApplicationContext implements BeanFactory { public Map<String, Object> beanMap = new HashMap<>(); public ClassPathXmlApplicationContext () { ClassPathXmlApplicationContext("applicationContext.xml"); } // 初始化获取 beanMap public ClassPathXmlApplicationContext (String path) throw Exception { // 转化 path 为流 InputStream is = this.getClass().getClassLoader().getResourceAsStream(path); // 获取 document 对象 DocumentBuildFactory dbf = DocumentBuildFactory.newInstance(); DocumentBuild db = dbf.newDocumentBuild(); Document doc = db.parse(is); // 获取 nodeList NodeList nodeList = doc.getDocumentElement(); // 将 bean 节点放入 beanMap for (int i = 0; i < nodeList.getLength(); i++) { Node node = NodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) node; String id = element.getAttribute("id"); String clazz = element.getAttribute("class"); // 反射获取 class Object beanObj = Class.forName(clazz).newInstance(); beanMap.put(id, beanObj); } } for (int i = 0; i < nodeList.getLength(); i++) { Node node = nodeList.item(i); if (node.getNodeType() == Node.ELEMENT_NODE) { // 获取子节点 property Element baseBean = (Element) node; String baseId = baseBean.getAttribute("id"); NodeList childNodes = node.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { Node property = childNodes.item(j); if (property.getNodeType() == Node.ELEMENT_NODE) { Element propertyEle = (Element) property; String name = propertyEle.getAttribute("name"); String ref = propertyEle.getAttribute("ref"); Object baseObj = beanMap.get(baseId); Object refObj = beanMap.get(ref); // 反射获取成员变量 Field dependency = baseObj.getClass().getDeclaredField(name); dependency.setAccessible(true); // 设置依赖 dependency.set(baseObj, refObj); } } } } } @Override public Object getBean (String id) { return beanMap.get(id); } }
-
DispatcherServlet 中央控制器
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
public class DispatcherServlet implements HttpServlet { public BeanFactory beanFactory; @Override public void init () throw ServletException { ServletContext application = this.getServletContext(); Object beanFactoryObj = application.getAttribute("beanFactory"); if (beanFactoryObj != null) { beanFactory = (BeanFactory) beanFactory; }else { throw new RuntimeException("Ioc 容器获取失败!"); } } @Override public void service (HttpServletRequest request, HttpServletResponse response) throw ServletException, IOException, IllegalAccessException, InvocationTargetException { request.setCharacterEncoding("UTF-8"); // 获取路径并分割 String uri = request.getServletPath().substring(1); // /fruit?operate=add -> fruit?.. String beanName = uri.contains("?") ? uri.substring(0, uri.indexOf("?") : uri); String operate = request.getParameter("operate"); if (operate == null || "".equals(operate)) { operate = "index"; } // 通过 beanName 获取对应实体类 Object beanObj = Class.forName(beanName).newInstance(); // 获取对应 operate Method[] methods = beanObj.getClass().getDeclaredMethods(); for (Method method : methods) { String methodName = method.getName(); if (operate.equals(methodName)) { // 获取参数 Parameter[] parameter = method.getParameters(); Object[] paramVal = new Object[parameter.length]; for (int i = 0; i < parameters.length; i++) { if (parameters[i].getType().getName().contains("request")) { paramVal[i] = request; } else if (parameters[i].getType().getName().contains("response")) { paramVal[i] = response; } } method.setAccessible(true); method.invoke(beanObj, paramVal); } } } }
-