Spring IOC &DI

Spring IOC &DI

三层架构介绍

在实际开发中需要尽可能让每一个接口、类、方法的职责更加单一(单一职责原则)

单一职责原则:一个类或者一个方法、就制作一件事情、只管一块功能。

这样就可以让类、接口、方法的负责度更低、可读性强、扩展性强、利于后期维护。

三层架构思想改造程序

控制层:

接收前端发送的请求、对请求进行处理、并响应数据。

@RestController
public class EmpController {
    //业务层对象
    private EmpService empService = new EmpServiceA();

    @RequestMapping("/listEmp")
    public Result list(){
        //1. 调用service层, 获取数据
        List<Emp> empList = empService.listEmp();

        //3. 响应数据
        return Result.success(empList);
    }
}
业务层:

处理业务具体逻辑

业务接口
//业务逻辑接口(制定业务标准)
public interface EmpService {
    //获取员工列表
    public List<Emp> listEmp();
}
业务实现类
//业务逻辑实现类(按照业务标准实现)
public class EmpServiceA implements EmpService {
    //dao层对象
    private EmpDao empDao = new EmpDaoA();

    @Override
    public List<Emp> listEmp() {
        //1. 调用dao, 获取数据
        List<Emp> empList = empDao.listEmp();

        //2. 对数据进行转换处理 - gender, job
        empList.stream().forEach(emp -> {
            //处理 gender 1: 男, 2: 女
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else if("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}
数据访问层

负责数据访问操作、包含数据增删改查

//数据访问层接口(制定标准)
public interface EmpDao {
    //获取员工列表数据
    public List<Emp> listEmp();
}

分层解耦

内聚:软件中个功能模块的功能联系

耦合:软件中各个层/模块之间的依赖、关联程度。

软件设计原则:高内聚、低耦合

高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 “高内聚”。

低耦合指的是:软件中各个层、模块之间的依赖关联程序越低越好。

解耦

使用Spring中的两个核心概念

控制反转(IOC)
对象的创建权由人为主动转移到容器(由容器创建、管理对象)。
这个容器叫做:IOC容器或Spring容器
依赖注入(DI)
容器为程序提供运行时所需要的依赖的资源----依赖注入

IOC容器创建的、管理的对象叫做bean对象

IOC&DI实现步骤

  • 使用Spring提供的注解 :@component将实现类交给容器进行管理
  • 为Controller和service注入运行时所依赖的对象:@Autowired实现程序运行时IOC容器自动注入所依赖的对象

Controller层:

@RestController
public class EmpController {
    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpService empService ;

    @RequestMapping("/listEmp")
    public Result list(){
        //1. 调用service, 获取数据
        List<Emp> empList = empService.listEmp();

        //3. 响应数据
        return Result.success(empList);
    }
}

Service层:

@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpServiceA implements EmpService {

    @Autowired //运行时,从IOC容器中获取该类型对象,赋值给该变量
    private EmpDao empDao ;

    @Override
    public List<Emp> listEmp() {
        //1. 调用dao, 获取数据
        List<Emp> empList = empDao.listEmp();

        //2. 对数据进行转换处理 - gender, job
        empList.stream().forEach(emp -> {
            //处理 gender 1: 男, 2: 女
            String gender = emp.getGender();
            if("1".equals(gender)){
                emp.setGender("男");
            }else if("2".equals(gender)){
                emp.setGender("女");
            }

            //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导
            String job = emp.getJob();
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("就业指导");
            }
        });
        return empList;
    }
}

Dao层:

@Component //将当前对象交给IOC容器管理,成为IOC容器的bean
public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1. 加载并解析emp.xml
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        System.out.println(file);
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

IOC详解

在之前的入门案例中,要把某个对象交给IOC容器管理,需要在类上添加一个注解:@Component

而Spring框架为了更好的标识web应用程序开发当中,bean对象到底归属于哪一层,又提供了@Component的衍生注解:

  • @Controller (标注在控制层类上)
  • @Service (标注在业务层类上)
  • @Repository (标注在数据访问层类上)

要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一:

注解说明位置
@Controller@Component的衍生注解标注在控制器类上
@Service@Component的衍生注解标注在业务类上
@Repository@Component的衍生注解标注在数据访问类上(由于与mybatis整合,用的少)
@Component声明bean的基础注解不属于以上三类时,用此注解

注意事项

声明bean的时候、可以通过value属性指定bean的名字、如果没有指定、默认为类名首字母小写

在SpringBoot集成web开发中 声明控制器只能用@controller

组件扫描

在声明的四大注解声明bean时、需要被扫描才能生效@ComponentScan扫描

默认扫描范围是SpringBoot启动类所在包及其子包

在实际开发中应注意SpringBoot启动类所在位置

DI详解

在之前实现依赖注入时、使用的是@Autowired实现。

@Autowired注解默认是按照类型进行自动装配的(在IOC容器中去找某个类型对应的对象、然后完成注入操作)

当在IOC容器中出现多个相同类型的bean对象时

![在这里插入图片描述](https://img-blog.csdnimg.cn/600c017b875b429282b27e09a9be00d7.png#pic_center

程序会出现错误、因为此时 无法识别使用哪个容器

在这里插入图片描述

为解决以上问题Spring提供了以下几种方案

  • @Primary
  • @Qualifier
  • @Resource

@Primary注解:当存在多个相同类型的bean时,给要使用的类加上@primary注解、确定使用哪个注解进行对象注入

在这里插入图片描述

使用@Qualifier注解:指定当前要注入的bean对象。 在@Qualifier的value属性中,指定注入的bean的名称。

  • @Qualifier注解不能单独使用,必须配合@Autowired使用

在这里插入图片描述

使用@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

在这里插入图片描述

@Autowird 与 @Resource的区别

@Autowird是Spring框架提供的注解。而@Resource是JDK提供的

@Autoweird是按照类型注入 而@Resource是按照名称注入

@Autowired使用

[外链图片转存中…(img-HjPCNY0D-1689415013671)]

使用@Resource注解:是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。

[外链图片转存中…(img-zcHP9BjS-1689415013672)]

@Autowird 与 @Resource的区别

@Autowird是Spring框架提供的注解。而@Resource是JDK提供的

@Autoweird是按照类型注入 而@Resource是按照名称注入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值