• mvc-ioc实现


    mvc-ioc实现

    1. IOC(Inversion of Control):控制反转
    2. 1) 耦合/依赖
    3. 依赖指的是某某某离不开某某某
    4. 在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
    5. 我们系统架构或者是设计的一个原则是: 高内聚低耦合。
    6. 层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
    7. 2) IOC - 控制反转 / DI - 依赖注入

    BeanFactory 接口

    1. public interface BeanFactory {
    2. Object getBean(String id);
    3. }

    ClassPathXmlApplicationContext 类

    1. public class ClassPathXmlApplicationContext implements BeanFactory {
    2. private Map beanMap = new HashMap<>();
    3. public ClassPathXmlApplicationContext() {
    4. try {
    5. InputStream inputStream = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
    6. //1.创建DocumentBuilderFactory对象
    7. DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    8. //2.创建DocumentBuilder对象
    9. DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    10. //3.创建Document对象
    11. Document document = documentBuilder.parse(inputStream);
    12. //4.获取所有的bean节点
    13. NodeList beanNodeLists = document.getElementsByTagName("bean");
    14. for (int i = 0; i < beanNodeLists.getLength(); i++) {
    15. Node beanNode = beanNodeLists.item(i);
    16. //判断该节点的类型是否等于元素节点
    17. if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
    18. Element beanElement = (Element) beanNode;
    19. String beanId = beanElement.getAttribute("id");
    20. String className = beanElement.getAttribute("class");
    21. Class beanClass = Class.forName(className);
    22. //创建bean实例
    23. Object beanObj = beanClass.newInstance();
    24. //将bean实例对象保存到map容器中
    25. beanMap.put(beanId, beanObj);
    26. //到目前为止,此处需要注意的是:bean和bean之间的依赖关系还没有设置
    27. }
    28. }
    29. //5.组装bean之间的依赖关系
    30. for (int i = 0; i < beanNodeLists.getLength(); i++) {
    31. Node beanNode = beanNodeLists.item(i);
    32. //判断该节点的类型是否等于元素节点
    33. if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
    34. Element beanElement = (Element) beanNode;
    35. String beanId = beanElement.getAttribute("id");
    36. NodeList beanChildNodeList = beanElement.getChildNodes();
    37. for (int j = 0; j < beanChildNodeList.getLength(); j++) {
    38. Node beanChildNode = beanChildNodeList.item(j);
    39. if (beanChildNode.getNodeType() == Node.ELEMENT_NODE && "property".equals(beanChildNode.getNodeName())) {
    40. Element propertyElement = (Element) beanChildNode;
    41. String propertyName = propertyElement.getAttribute("name");
    42. String propertyRef = propertyElement.getAttribute("ref");
    43. //1.找到propertyRef对应的实例
    44. Object refObj = beanMap.get(propertyRef);
    45. //2.将refObj设置到当前bean对应的实例的property属性上去
    46. Object beanObj = beanMap.get(beanId);
    47. Class beanClass = beanObj.getClass();
    48. Field propertyField = beanClass.getDeclaredField(propertyName);
    49. propertyField.setAccessible(true);
    50. propertyField.set(beanObj, refObj);
    51. }
    52. }
    53. }
    54. }
    55. } catch (ParserConfigurationException e) {
    56. e.printStackTrace();
    57. } catch (SAXException e) {
    58. e.printStackTrace();
    59. } catch (IOException e) {
    60. e.printStackTrace();
    61. } catch (IllegalAccessException e) {
    62. e.printStackTrace();
    63. } catch (InstantiationException e) {
    64. e.printStackTrace();
    65. } catch (ClassNotFoundException e) {
    66. e.printStackTrace();
    67. } catch (NoSuchFieldException e) {
    68. e.printStackTrace();
    69. }
    70. }
    71. @Override
    72. public Object getBean(String id) {
    73. return beanMap.get(id);
    74. }
    75. }

    FruitController 类

    1. //FruitServlet 改名为 FruitController
    2. public class FruitController{
    3. private FruitService fruitService = null;
    4. private String update(Integer fid,String fname,Integer price,Integer fcount,String remark){
    5. //3.执行更新
    6. fruitService.updateFruit(new Fruit(fid, fname, price, fcount, remark));
    7. //4.资源跳转
    8. //super.processTemplate("index",request,response);
    9. //request.getRequestDispatcher(index.html).forward(request,response);
    10. //此处需要重定向,目的是重新给IndexServlet发请求,重新获取fruitList,然后覆盖到session
    11. //这样index.html页面上显示的session中的数据才是最新的
    12. //response.sendRedirect("fruit.do");
    13. return "redirect:fruit.do";
    14. }
    15. private String edit(Integer fid,HttpServletRequest request){
    16. if (fid != null) {
    17. Fruit fruit = fruitService.getFruitByFid(fid);
    18. request.setAttribute("fruit", fruit);
    19. //super.processTemplate("edit", request, response);
    20. return "edit";
    21. }
    22. return "error";
    23. }
    24. private String del(Integer fid){
    25. if (fid != null) {
    26. fruitService.delFruit(fid);
    27. //response.sendRedirect("fruit.do");
    28. return "redirect:fruit.do";
    29. }
    30. return "error";
    31. }
    32. private String add(String fname,Integer price,Integer fcount,String remark){
    33. Fruit fruit = new Fruit(0, fname, price, fcount, remark);
    34. fruitService.addFruit(fruit);
    35. //response.sendRedirect("fruit.do");
    36. return "redirect:fruit.do";
    37. }
    38. private String index(String oper,String keyword,Integer pageNo,HttpServletRequest request){
    39. HttpSession session = request.getSession();
    40. if (pageNo == null){
    41. pageNo = 1;
    42. }
    43. //如果oper != null 说明是通过表单的查询按钮点击过来的
    44. //如果oper是空的,说明不是通过表单的查询按钮点击过来的
    45. if (StringUtil.isNotEmpty(oper) && "search".equals(oper)) {
    46. //说明是点击表单查询发送过来的请求
    47. //此时,pageNo应该还原为1,keyword应该从请求参数获取
    48. pageNo = 1;
    49. //如果keyword为null,需要设置为空字符串"",否则查询时会拼接成 %null%
    50. //我们期望的是 %%,就是查询所有的数据
    51. if (StringUtil.isEmpty(keyword)) {
    52. keyword = "";
    53. }
    54. //将 keyword 保存(覆盖)到session中
    55. session.setAttribute("keyword", keyword);
    56. } else {
    57. //说明此处不是点击表单查询发送过来的请求(比如点击下面的上一页下一页或者直接在地址栏输入网址)
    58. //此时keyword应该从session作用域获取
    59. //如果不是点击的查询按钮,那么查询是基于session中保存的现有的keyword进行查询
    60. Object keywordobj = session.getAttribute("keyword");
    61. if (keywordobj != null) {
    62. keyword = (String) keywordobj;
    63. } else {
    64. keyword = "";
    65. }
    66. }
    67. //重新更新当前页的值
    68. session.setAttribute("pageNo", pageNo);
    69. List fruitList = fruitService.getFruitList(keyword, pageNo);
    70. session.setAttribute("fruitList", fruitList);
    71. //总记录条数
    72. int pageCount = fruitService.getPageCount(keyword);
    73. /*
    74. 总记录条数 总页数
    75. 1 1
    76. 5 1
    77. 6 2
    78. 10 2
    79. 11 3
    80. fruitCount (fruitCount+5-1)/5
    81. */
    82. session.setAttribute("pageCount", pageCount);
    83. //此处的视图名称是index
    84. //那么thymeleaf会将这个 逻辑视图 名称对应到 物理视图 名称上去
    85. // //逻辑视图名称:index
    86. //物理视图名称: viw-prefix + 逻辑视图名称 +view-suffix
    87. //所以真实的视图名称是: / index .html
    88. //super.processTemplate("index", request, response);
    89. return "index";
    90. }
    91. }

    FruitService 接口

    1. public interface FruitService {
    2. //获取指定页面的库存列表信息
    3. List getFruitList(String keyword, Integer pageNo);
    4. //添加库存记录信息
    5. void addFruit(Fruit fruit);
    6. //根据id查看指定库存记录
    7. Fruit getFruitByFid(Integer fid);
    8. //删除特定库存记录
    9. void delFruit(Integer fid);
    10. //修改特定库存记录
    11. void updateFruit(Fruit fruit);
    12. //获取总页数
    13. Integer getPageCount(String keyword);
    14. }

    FruitServiceImpl 类

    1. public class FruitServiceImpl implements FruitService{
    2. private FruitDAO fruitDAO = null;
    3. @Override
    4. public List getFruitList(String keyword, Integer pageNo) {
    5. return fruitDAO.getFruitList(keyword,pageNo);
    6. }
    7. @Override
    8. public void addFruit(Fruit fruit) {
    9. fruitDAO.addFruit(fruit);
    10. }
    11. @Override
    12. public Fruit getFruitByFid(Integer fid) {
    13. return fruitDAO.getFruitByFid(fid);
    14. }
    15. @Override
    16. public void delFruit(Integer fid) {
    17. fruitDAO.delFruit(fid);
    18. }
    19. @Override
    20. public void updateFruit(Fruit fruit) {
    21. fruitDAO.updateFruit(fruit);
    22. }
    23. @Override
    24. public Integer getPageCount(String keyword) {
    25. int count = fruitDAO.getFruitCount(keyword);
    26. int pageCount = (count + 5 - 1) / 5;
    27. return pageCount;
    28. }
    29. }

    applicationContext.xml

    1. "1.0" encoding="utf-8"?>
    2. <beans>
    3. <bean id="fruitDAO" class="com.atguigu.fruit.dao.impl.FruitDAOImpl"/>
    4. <bean id="fruitService" class="com.atguigu.fruit.service.impl.FruitServiceImpl">
    5. <property name="fruitDAO" ref="fruitDAO"/>
    6. bean>
    7. <bean id="fruit" class="com.atguigu.fruit.controllers.FruitController">
    8. <property name="fruitService" ref="fruitService"/>
    9. bean>
    10. beans>

  • 相关阅读:
    EdgeX Foundry MQTT设备服务
    羊了个羊网页版
    【微服务】CentOS7 虚拟机 安装 Docker
    海康的资料
    深度之眼(二十三)——Python:Sklearn库
    Mybatis练习案例
    Java学习笔记(五)——数组、排序和查找
    Linux操作系统:性能指标监控与通知
    ansible角色部署lamp架构
    自动驾驶技术的基础知识
  • 原文地址:https://blog.csdn.net/weixin_52385232/article/details/127112969