【Spring】07 后续的学习补充 vol1

摘要:
我有点困惑,但这不是重点。获取对象的下一种方法是从容器中获取它,这需要密钥作为参数:添加泛型,因此我们不需要进行强转换。但有一个问题,dao也是一个接口。在指向接口之后,无法设置setter,但是我们不能设置接口来处理className。它应该叫做beanName。现在我们可以通过配置文件获取对象,整个过程中没有新单词。

控制反转Inverse Of Control的演变:

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

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

由GradeDao接口指向GradeDaoImpl

【Spring】07 后续的学习补充 vol1第1张

再由GradeService指向GradeServiceImpl

【Spring】07 后续的学习补充 vol1第2张

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

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

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

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

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

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

【Spring】07 后续的学习补充 vol1第3张

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

虽然这还是硬编码中

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

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

【Spring】07 后续的学习补充 vol1第4张

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

【Spring】07 后续的学习补充 vol1第5张

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

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

首先是配置文件:bean.properties

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

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

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

然后改造我们的BeanFactory

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

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

【Spring】07 后续的学习补充 vol1第6张

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

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

这就需要key作为参数:

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

【Spring】07 后续的学习补充 vol1第7张

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

className应该换成叫beanName

【Spring】07 后续的学习补充 vol1第8张

现在我们通过配置文件的方式来获取对象,整个过程完全看不到一个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>

免责声明:文章转载自《【Spring】07 后续的学习补充 vol1》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇今日重新安装go和liteide,记录一下过程[转]基于SQL脚本将数据库表及字段提取为C#中的类下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

记druid 在配置中心下的一个大坑: cpu 达到 100%

把我们的dubbo 应用移步到配置中心上去之后,发现我们的应用过一段时间就会出现cpu 100%的情况 (大概是12个小时),一开始cpu占用是2-5% 的样子,什么都没做,后面竟然用尽了cpu。。 把jvm 线程堆栈打印一下,发现线程数竟然达到了上万..... 发现最多是这样的一个线程: "com.alibaba.nacos.client.Worker....

Spring 框架的事务管理

1. Spring 框架的事务管理相关的类和API PlateformTransactionManager 接口: 平台事务管理器(真正管理事务的类); TransactionDefinition 接口: 事务定义信息(事务的隔离级别,传播行为,超时,只读等); TransactionStatus 接口: 事务的状态; 平台事务管理器真正管理事务对...

【转】java异常报错大全

算术异常类:ArithmeticExecption 空指针异常类:NullPointerException 类型强制转换异常:ClassCastException 数组负下标异常:NegativeArrayException 数组下标越界异常:ArrayIndexOutOfBoundsException 违背安全原则异常:SecturityExceptio...

JAVA反射之内省

JavaBean: 就是一个java类 属性全部私有,提供公有的getter,setter方法 提供一个无参的构造方法 类必须公有,必须打包 JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。 内省API: Introspector类: 构建一个全面描述目标 bean 的 BeanInfo 对象 BeanInfo接口:封装bean...

maven 打包时自定义变量的使用

  maven打包时,如果有一些变量在多个地方使用,可以使用-D的方式或者properties的方式。        使用-D的方式或者properties的方式定义的变量,在Dockfile或者shell脚本或者pom中都可以被动态的替换为期望的值。       原文地址:https://blog.csdn.net/feier7501/article/d...

java加载properties配置文件的几种方法

 自由自在 废话省略... 1.普通方法 直接上我写的一共配置文件获取类: 配置文件 socket.server.address = 127.0.0.1 socket.server.port = 8511 socket.connect.timeout = 3000 package com.adao.common; import java.io.IOExc...