Servlet-api
一、Servlet生命周期中的初始化
-
Servlet中的初始化有两个初始化方法:
init()
// 源码 public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); }
init(config)
// 源码 public void init() throws ServletException { }
-
可以重写init方法做一些准备工作,然后再通过如下方法获取初始化数据
// 获取config参数 ServletConfig config = getServletConfig(); // 获取初始化参数值 config.getInitParameter(key)
-
在web.xml文件中配置Servlet
<!-- 使用@WebServlet中的同等配置写法 @WebServlet(urlPattern{"/demo01"}, initParams{ @WebInitParam(name="hello",value="world"), @WebInitParam(name="uname",value="ok") } ) --> <servlet> <servlet-name>Demo01Servlet</servlet-name> <servlet-class>com.atguigu.servlet.Demo01Servlet</servlet-class> <init-param> <param-name>hello</param-name> <param-value>world</param-value> </init-param> <init-param> <param-name>uname</param-name> <param-value>ok</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Demo01Servlet</servlet-name> <url-pattern>/demo01</url-pattern> </servlet-mapping>
-
重写的init方法
public class Demo01Servlet extends HttpServlet { @Override public void init() throws ServletException { ServletConfig config = getServletConfig(); String initValue = config.getInitParameter("hello"); // 输出为:word System.out.println("initValue = " + initValue); ServletContext servletContext = getServletContext(); String contextConfigLocation = servletContext.getInitParameter("contextConfig"); // 输出为:classpath:applicationContext.xml System.out.println("contextConfig = " + contextConfigLocation); } }
二、Servlet中的ServletContext和< context-param >
-
web.xml中的context配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
-
获取ServletContext
// 在init方法中,直接使用getServletContext方法 ServletContext servletContext = getServletContext(); String contextConfigLocation = servletContext.getInitParameter("contextConfig"); // 在service方法中,使用req/session调用getServletContext方法 @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext servletContext = req.getServletContext(); String context = servletContext.getInitParameter("contextConfig"); System.out.println("context = " + context); HttpSession session = req.getSession(); ServletContext servletContext1 = session.getServletContext(); String context1 = servletContext1.getInitParameter("contextConfig"); System.out.println("context1 = " + context1); }
三、业务层
-
MVC:软件开发中的一个经典的架构模式
Model(模型)、View(视图)、Controller(控制)
视图层:用于做数据展示以及用户交互的一个界面
控制层:能够接收客户端的请求,具体的业务功能还是需要借助于模型组件来完成
模型层:① pojo: Java对象(即:数据载体,对应数据表中的一条数据),实际就是普通JavaBeans,
② DAO:数据访问对象,对具体数据表的增删改查的各单一操作。
③ BO: 业务对象,针对具体现实功能的实现
-
区分业务对象和数据访问对象
DAO:内部的方法都属于单精度方法/细粒度方法。即一个方法只考虑一个事件,如添加就是一个insert方法
BO:内的方法属于业务方法,功能比较复杂,粒度较粗。
举例如下:
注册这个功能属于业务功能,也就是属于业务方法,内部包含了多个DAO方法,通过对这些方法的组合调用实现功能
-
在客户管理系统中加入业务层的逻辑图
四、IOC
-
耦合/依赖
在软件系统中,层与层之间存在依赖,我们称之为耦合。
系统架构的设计原则:高内聚低耦合
层内部的组成应该是高度聚合,层与层治安的关系应该是低耦合,最理想的情况是0耦合
-
通过xml文件减少耦合
-
xml的基本介绍
3.1 概念:
XML: Extensible Markup Language,可扩展型标记语言
HTML:HyperText Markup Language,超文本标记语言
HTML是XML的一个子集3.2 xml文件包含三个部分
声明:必须有,而且该声明代码必须在XML文件的第一行,固定写法:<?xml version=“1.0”
encoding=“utf-8”?>
DTD 文档定义
XML正文:内部的标签可以随意命名使用3.3 路径:
注意,该xml配置文件是在src文件夹下
3.4 Node,节点对象,包括下面两种节点
Element:元素节点
Text:文本节点
五、增加业务层,并通过xml配置减少耦合
-
在客户端和controller之间再增加一个业务层,将原先在dispatcher类(即servlet组件)内的对于xml文件解析的功能代码提取出来,减少servlet组件的耦合度
// 一、创建一个接口,针对xml文件内的bean标签的获取 public interface BeanFactory { Object getBean(String id); } // 二、创建一个该接口的实现类,用于解析xml文件中的bean标签,并实现标签的获取 public class ClassPathXmlApplication implements BeanFactory{ private Map<String,Object> beanMap = new HashMap<>(); public ClassPathXmlApplication() { try { InputStream is = getClass().getClassLoader().getResourceAsStream("applicationContext.xml"); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(is); // 1.获取各bean标签,并存入beanMap集合中 NodeList beanNodeList = document.getElementsByTagName("bean"); for (int i = 0; i < beanNodeList.getLength() ; i++) { Node beanNode = beanNodeList.item(i); if (beanNode.getNodeType() == Node.ELEMENT_NODE) { Element beanElement = (Element)beanNode; String beanId = beanElement.getAttribute("id"); String className = beanElement.getAttribute("class"); Class beanClass = Class.forName(className); Object beanObj = beanClass.newInstance(); beanMap.put(beanId,beanObj); // 上述只是将bean标签全部保存到了beanMap中,接下来进行bean之间依赖关系的配置 } } // 2.组装各bean之间的依赖关系,尽可能解耦 for (int i = 0; i < beanNodeList.getLength(); i++) { // 2.1 获取其中一个bean标签 Node beanNode = beanNodeList.item(i); // 2.2 确定该节点的类型是否为元素节点 if (beanNode.getNodeType() == Node.ELEMENT_NODE) { // 2.3 如果是元素节点,就将其从Node节点类型强转为Element元素节点类型 Element beanElement = (Element) beanNode; // 2.4 再次获取该标签id中的值 String beanId = beanElement.getAttribute("id"); // 2.5 解析该元素节点的子节点 NodeList childNodesList = beanElement.getChildNodes(); for (int j = 0; j < childNodesList.getLength(); j++) { Node beanChildNode = childNodesList.item(j); // 2.6 解析节点名为”property“的子节点 if (beanChildNode.getNodeType() == Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())){ Element beanChildElement = (Element)beanChildNode; // 2.6.1 name对应的是该bean标签中类中的属性名 String propertyName = beanChildElement.getAttribute("name"); String propertyRef = beanChildElement.getAttribute("ref"); // 2.6.2 ref对应着与之匹配的bean的id Object beanRef = beanMap.get(propertyRef); // 2.6.3 通过beanId,从集合中取出该bean标签中的类 Object beanObj = beanMap.get(beanId); // 2.6.4 通过反射,获取该对象对应类中propertyName对应的属性 Class beanObjClazz = beanObj.getClass(); Field propertyField = beanObjClazz.getDeclaredField(propertyName); propertyField.setAccessible(true); // 2.7 将匹配bean中的类的对象beanRef赋值给属性,实现解耦 propertyField.set(beanObj,beanRef); } } } } } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } } @Override public Object getBean(String id) { return beanMap.get(id); } }
-
xml配置文件,建立层与层之间的关联
<?xml version="1.0" encoding="utf-8"?> <!-- 新建一个beans标签,在该标签内,对每个bean进行具体配置 --> <beans> <bean id="customersDAO" class="com.atguigu.consrumers.dao.ListIpm"/> <bean id="customersService" class="com.atguigu.consrumers.service.impl.CustomersServiceImpl" > <!-- property标签用来表示属性:name表示该类内的属性名;ref表示引用其它bean的id值 建立了service层和DAO层之间的关联 --> <property name="baseDAO" ref="customersDAO" /> </bean> <bean id="customers" class="com.atguigu.consrumers.controllers.CustomersController" > <!-- 建立controller层和service层之间的关联 --> <property name="cService" ref="customersService"/> </bean> </beans>
-
模型层 - - 业务
public class CustomersServiceImpl implements CustomersService { private ListIpm baseDAO = null; @Override public List<Customers> getList(Connection conn, String str, int pageOn) { ···
-
控制层
public class CustomersController { private CustomersServiceImpl cService = null; ···
-
视图层
@WebServlet("*.do") public class DispatcherServlet extends ViewBaseServlet{ private BeanFactory beanFactory; @Override public void init() throws ServletException { super.init(); beanFactory = new ClassPathXmlApplication(); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws IOException { ···