zoukankan      html  css  js  c++  java
  • 【Spring】07 后续的学习补充 vol1

    控制反转Inverse Of Control的演变:

    在之前的原生Javaweb项目的问题:

    我们三层架构每一层之间的联系是这样的:

    由GradeDao接口指向GradeDaoImpl

    再由GradeService指向GradeServiceImpl

    但是我们发现,如果这样写死在每一层的硬编码中的话,那么接口的存在就失去了意义

    对象的创建是由这个上层的内部所决定

    我们是希望每一层的联系最小化,但是又不能完全隔绝关系,组件就像组装的好的零件

    相互之间的依赖降低到最小,比如这个daoImpl我需要替换,就根据实现的dao接口就可以有

    MySQL实现,Oracle实现,PostgreSQL实现等等

    对象的创建可以移交到外部,我们在内部设置setter注入即可,或者使用带参构造器

    通过setter或者带参构造器,我们可以从本层的内部创建对象这个控制权力,移交到了外面

    虽然这还是硬编码中

    接下来我们就创建一个工厂类,由工厂实现对象的创建,而这个行为,非常像生产产品

    一个个对象即我们的业务的产品

    对象的注入交由工厂生产给予

    但是我们是不是发现,工厂的产品还是固定的?然后再像Jdbc一样,

    通过读取配置文件的形式解除耦合

    首先是配置文件:bean.properties

    例如这里我就配置另外一种实现

    AaaDao = ioc.dao.AaaDaoImpl2
    AaaService = ioc.service.AaaServiceImpl2

    这里只是键值对简单的字符串

    然后改造我们的BeanFactory

    通过加载的时候读取配置文件直接生成对象放进这个map容器中

    这个容器不就是bean的容器了吗,键对应的实现类名,值即对象

    put放进去的key应该换value进去。。。我有点分不清

    但这不是重点,我们下面获取对象的方法就是从容器里面获取

    这就需要key作为参数:

    再加上泛型,这样我们就不需要进行强转了

    但是有个问题就是dao也是接口啊,接口指向了之后没办法在setter了,但是可以不设置接口处理

    className应该换成叫beanName

    现在我们通过配置文件的方式来获取对象,整个过程完全看不到一个new字。

    总结:写的好烂,过程改了好几回

    瞎扯的代码:

    Bean工厂

    package ioc;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    
    /**
     * @author DaiZhiZhou
     * @file OA-Project
     * @create 2020-07-24 22:57
     */
    public class BeanFactory {
    
        private static Map<String,Object> beanContainer = new HashMap<>();
    
        static {
            try {
                // InputStream inputStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
           // 因为找不到配置文件就检查下路径的读取
                String file = BeanFactory.class.getClassLoader().getResource("bean.properties").getFile();
                System.out.println(file);
                InputStream inputStream = new FileInputStream(new File(file));
    
                Properties properties = new Properties();
                properties.load(inputStream);
    
                Enumeration<Object> keys = properties.keys();
    
                while (keys.hasMoreElements()) {
                    String key = (String)keys.nextElement();
                    String value = properties.getProperty(key);
    
                    Class<?> classByValue = Class.forName(value);
                    Object valueInstance = classByValue.newInstance();
                    beanContainer.put(key, valueInstance);
                }
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static <Bean>Bean getBean(String className, Class<Bean> beanClass) {
            Object o = beanContainer.get(className);
            return (Bean)o;
        }
    
    }

    properties:

    AaaDao = ioc.dao.AaaDaoImpl2
    AaaService = ioc.service.AaaServiceImpl2

    测试类:假装是视图的Servlet

    package ioc.servlet;
    
    import ioc.BeanFactory;
    import ioc.dao.AaaDao;
    import ioc.dao.AaaDaoImpl;
    import ioc.service.AaaService;
    import ioc.service.AaaServiceImpl;
    import ioc.service.AaaServiceImpl2;
    import org.junit.Test;
    
    /**
     * @author DaiZhiZhou
     * @file OA-Project
     * @create 2020-07-24 22:48
     */
    public class AaaServletFake {
    
        private AaaService aaaService;
    
        public void setAaaService(AaaService aaaService) {
            this.aaaService = aaaService;
        }
    
        @Test
        public void toAaaListPage() {
            setAaaService(new AaaServiceImpl(new AaaDaoImpl()));
            aaaService.getAaaList();
        }
    
        @Test
        public void toAaaListPageByFactoryProduct() {
            //this.setAaaService(BeanFactory.getAaaService());
            aaaService.getAaaList();
        }
    
        @Test
        public void toAaaListPageByFactoryProductPropertyFileInject() {
            AaaDao aaaDao = BeanFactory.getBean("AaaDao", AaaDao.class);
            AaaServiceImpl2 aaaServiceImpl2 = BeanFactory.getBean("AaaService", AaaServiceImpl2.class);
            aaaServiceImpl2.setAaaDao(aaaDao);
            this.setAaaService(aaaServiceImpl2);
            this.aaaService.getAaaList();
        }
    
    }

    关于注入问题的再补充:

    因为存在这种工厂方式的注入,所以Spring就也提供了对应的这种方式:

    静态工厂获取 和 工厂实例方法获取:

    详细见:

    http://123.57.58.29/blog/1591625710261

    静态工厂

        <!-- 此种方式是:  
         使用 StaticFactory 类中的静态方法 createAccountService 创建对象,并存入 spring 容器 
           id 属性:指定 bean 的 id,用于从容器中获取   
           class 属性:指定静态工厂的全限定类名   
           factory-method 属性:指定生产对象的静态方法  
         -->
        
           <bean id="accountService" class="com.tc51.factory.StaticFactory" factory-method="createAccountService"></bean>

    实例工厂

      <!--创建工厂对象-->
        <!--先通过实例工厂创建对象-->
        <bean id="bean3Factory" class="com.tc51.factory.Bean3Factory"></bean>
        <bean id="accountService" factory-bean="bean3Factory" factory-method="createAccountService"></bean>
  • 相关阅读:
    昨天又学到了dp
    LeetCode面试题17.13
    leetcode971
    今天又一题,单调队列leetcode862
    今天学到了一招,LeetCode863
    今天一道简单题,数组排序LeetCode973
    es面试题
    es的常用配置
    es基础一张图
    JMeter中引入外部的JAR包给bean shell 使用
  • 原文地址:https://www.cnblogs.com/mindzone/p/13375219.html
Copyright © 2011-2022 走看看