JavaWEB十二:Servlet 之 初始化init、上下文Context 及 MVC设计模式雏形(模型 - 视图 - 控制)

Servlet-api

一、Servlet生命周期中的初始化
  1. Servlet中的初始化有两个初始化方法:

    init()
    // 源码 
    public void init(ServletConfig config) throws ServletException {
         this.config = config;
         this.init();
     }
    
    init(config)
     // 源码
     public void init() throws ServletException {
         
     }
    
  2. 可以重写init方法做一些准备工作,然后再通过如下方法获取初始化数据
    // 获取config参数
    ServletConfig config = getServletConfig();
    // 获取初始化参数值
    config.getInitParameter(key)
    
  3. 在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>   
    
  4. 重写的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 >
  1. web.xml中的context配置
     <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
     </context-param>
    
  2. 获取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);
    }
    
三、业务层
  1. MVC:软件开发中的一个经典的架构模式

    Model(模型)、View(视图)、Controller(控制)

    视图层:用于做数据展示以及用户交互的一个界面

    控制层:能够接收客户端的请求,具体的业务功能还是需要借助于模型组件来完成

    模型层:① pojo: Java对象(即:数据载体,对应数据表中的一条数据),实际就是普通JavaBeans,

    ​ ② DAO:数据访问对象,对具体数据表的增删改查的各单一操作。

    ​ ③ BO: 业务对象,针对具体现实功能的实现

  2. 区分业务对象和数据访问对象

    DAO:内部的方法都属于单精度方法/细粒度方法。即一个方法只考虑一个事件,如添加就是一个insert方法

    BO:内的方法属于业务方法,功能比较复杂,粒度较粗。

    举例如下:

    注册这个功能属于业务功能,也就是属于业务方法,内部包含了多个DAO方法,通过对这些方法的组合调用实现功能

  3. 在客户管理系统中加入业务层的逻辑图

    在这里插入图片描述

四、IOC
  1. 耦合/依赖

    在软件系统中,层与层之间存在依赖,我们称之为耦合。

    系统架构的设计原则:高内聚低耦合

    层内部的组成应该是高度聚合,层与层治安的关系应该是低耦合,最理想的情况是0耦合

  2. 通过xml文件减少耦合
  3. 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配置减少耦合
  1. 在客户端和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);
        }
    }
    
  2. 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>
    
  3. 模型层 - - 业务
    public class CustomersServiceImpl implements CustomersService {
        private ListIpm baseDAO = null;
        @Override
        public List<Customers> getList(Connection conn, String str, int pageOn) {
           ···
    
  4. 控制层
    public class CustomersController {
        private CustomersServiceImpl cService = null;
        ···
    
  5. 视图层
    @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 {
            ···
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

e_nanxu

感恩每一份鼓励-相逢何必曾相识

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值