java web 项目实现 耦合-解耦 解决方案----工厂模式入门级别

来源:互联网 发布:算法设计与分析pdf 编辑:程序博客网 时间:2024/05/03 04:30

1.主要思想就是使用工厂设计模式,将service层和dao层进行解耦

    控制反转就是(inversion of control)将控制权交个自定的一个工厂来实现,我们要做的就是,通过自定义beanfactory 得到需要的serviceiml 和 daoiml对应的类
说白了,不用serviceiml依赖dao层
 

这里使用ServletContextListener 监听器来让tomcat启动时,加载配置文件,

     这里就按照我自己的理解来说明,最近几天研究的结果,当然有老师指导的结果-----------黑马31期

  

    1,进行监听器的实现

      目的:可以第一时间加载配置文件


   2. 配置文件中注册监听器

     <!-- 注册Context监听器 -->
         <listener>


         <listener-class>com.itheima.ebs.web.Listener.ApplicationContextListener</listener-class>


         </listener>

   3,当监听器在tomcat启动时加载配置文件。配置文件名:applicationContext.xml (默认)

        public class ApplicationContextListener implements ServletContextListener {

         @Override
         public void contextInitialized(ServletContextEvent sce) {

          // 0 获得servletContext对象应用
          ServletContext context = sce.getServletContext();
          // 0.1加载配置
          String config = context.getInitParameter("config");

          if (config != null) {
           // 1.1 处理路径不同情况(我们都知道,配置文件,
           //可以放在src下面,可以放在web-inf下)
           String[] arr = config.split(":");
           //使用流的方式进行读取
           InputStream xmls = null;
           try {
           //如果放在classpath:applicationContext.xml
            if (arr.length == 2) {

             // 使用类加载器来加载配置文件
             xmls = ApplicationContextListener.class.getClassLoader()
               .getResourceAsStream(arr[1]);
            // 如果在WEB-INF下面
            } else if (arr.length == 1) {
            //使用servletContext的方法来加载
             xmls = context.getResourceAsStream(config); // 放到WEB-INF下
            }
           } catch (Exception e) {
            throw new RuntimeException("资源文件加载不成功" + config);
           }
           // 如果不等于Null,加载到了配置文件
           if (xmls != null) {
            // 2使用dom4j进行解析,为了方便查找,我们选在了map容器进行存储
            //定义了xmlUtil工具类,方便代码的维护--返回map集合
            Map<String, Bean> data = XmlUtil.parserBeanXml(xmls);
            //3 将解析结果放置到工厂中
            BeanFactory.setBeanData(data);
           }
          }
         }

           4.  我们使用dom4j进行解析:
             <beans>

                <bean name="CategoryDao" class="com.itheima.ebs.dao.impl.CategoryDaoImpl">

                </bean>

                <bean name="UserDao" class="com.itheima.ebs.dao.impl.UserDaoiml">

                </bean>
           
              </beans>


            public class XmlUtil {

            public static Map<String, Bean> parserBeanXml(InputStream xml) {

              try {
                   //定义一个容器
                  Map<String, Bean> data = new HashMap<String, Bean>();

                // 1解析文件,并获得Document对象
                SAXReader reader = new SAXReader();
                // 2.获取docuemnt
                Document document = reader.read(xml);
                // 3 得到 beans
                Element root = document.getRootElement();
                // 获得bean 元素集合
                List<Element> allBeanElements = root.elements();
                // 遍历取值(name:value  class:value)
                for (Element elements : allBeanElements) {

                  String beanName = elements.attributeValue("name");
                  String beanClass = elements.attributeValue("class");
                  // 为了后期方便对xml、
                  文件中配置扩展使用面向对象封装的思想将bean对象封装到特殊的 bean中
                  Bean bean = new Bean(beanName, beanClass);

                  data.put(beanName, bean);
                }
                //封装好的bean进行返回
                return data;
               
              } catch (Exception e) {
                throw new RuntimeException(e);
              }

            }

          5 .bean对象的封装

            package com.itheima.ebs.Factory;

          public class Bean {

           
            private String beanName;
            private String beanClass;
           
            public Bean() { }
           
            public Bean(String beanName, String beanClass) {
           
              this.beanName = beanName;
              this.beanClass = beanClass;
            }

              ---《 setter/getter方法 》----
           
          }

+++++++++++++++++++++++++++++++++++++++++++++++++++++
BeanFactory:

 beanfactory要提供一个自动生对应的bean对象,保证对象的唯一
  这里使用单例模式,加上反射思想,通过。class。fornam("类的全限定名").newInstance()

 

package com.itheima.ebs.Factory;

import java.util.Map;

/**
 *
 * 实例工厂-单例模式
 *
 * @return
 */
public class BeanFactory {

  private static BeanFactory factory = new BeanFactory();
  //存取bean的 key--value 的一个map对象
  private static Map<String, Bean> beanData;
  //bean 数据缓存集合
  private BeanFactory() {}
  public static BeanFactory getInstance() {
    return factory;
  }
  //向外部提供一个getbean的方法
  //因为是工厂类,所以不依赖任何外部类,使用object作为返回类型
  public Object getBean(String beanName) {
    try {
      //通过bean的名称--value(map.get(key)-----value)
      Bean bean=beanData.get(beanName);

      String beanclass=bean.getBeanClass();
      //初始化一个对象进行返回
      return Class.forName(beanclass).newInstance();
    } catch (Exception e) {
          throw new RuntimeException(e);
    }

  }
  public static void setBeanData(Map<String, Bean> beanData) {
    //从配置文件中读取bean信息传入工厂,从工厂往外取
    //使用提供一个set方法来共外界,将解析过的map容器,set到工厂中

    BeanFactory.beanData=beanData;
  }

}

这样一个简单的解耦,就可以实现了,我们就可以通过配置文件,来指定sevice层--serviceimpl

serviceimpl层和dao层,--dao层和daoimpl的解耦。互相不进行依赖。


     

     

 

 

0 0
原创粉丝点击