内聚与耦合
内聚 比如说我们刚刚书写的员工的实现类
在这里我们仅仅书写的是和员工相关的代码
而与员工无关的代码都没有放到这里
说明内聚程度较高
耦合
以后软件开发要高内聚 低耦合
提高程序灵活性 扩拓展性
分析代码
如何解耦
创建容器
提供一个容器 存储东西 存储EmpService类的实现
EmpController直接去容器中去找 又没有这个对象 复制给empService
有没有这个对象
控制反转与依赖注入
Springboot中很重要的概念
意思是如何操作运用容器
控制反转
是对象的创建控制权由应用程序转移到了外部容器 这个容器叫spring容器 ioc容器
依赖注入
是容器为应用程序提供运行时依赖的资源
Bean对象
表示IOC容器中创建管理的对象
IOC与DI的入门
控制反转和依赖注入的代码实现
我们需要完成controller层与service层的解耦
还有service层与dao层的解耦
具体代码程序
service层和dao层解耦 controller层和service层解耦
将两层中的对象删掉
程序会爆空指针异常
我们此时就需要用IOC和DI完成解耦操作
第一步 控制反转
第二步 需要ioc容器为其提供bean对象
启动springboot
部署后就可以访问服务端
如果以后我们在业务操作中要改变实现类
直接将需要交给控制层的核心逻辑层加上Component注释就行
再取消之前的实现类的注释
代表将当前实现类交给Bean容器管理
小结
控制反转:Component注解
将当前类交给IOC容器管理 成为IOC容器里的bean
依赖注入:Autowired注解
运行时,IOC容器会提供该类型的bean对象,并复制给该对象
代码实现
(只写了实现类)
java
package com.bigdate.threetier_architecture.dao.impl;
import com.bigdate.threetier_architecture.dao.EmpDao;
import com.bigdate.threetier_architecture.pojo.Emp;
import com.bigdate.threetier_architecture.util.XmlParserUtils;
import org.springframework.stereotype.Component;
import java.util.List;
//交给ioc容器处理 控制反转 称为ioc容器中的bean
@Component
public class EmpDaoA implements EmpDao {
@Override
public List<Emp> listEmp() {
String file=this.getClass().getClassLoader().getResource("emp.xml").getFile();
List<Emp>empList= XmlParserUtils.parse(file,Emp.class);
return empList;
}
}
java
package com.bigdate.threetier_architecture.service.impl;
import com.bigdate.threetier_architecture.dao.EmpDao;
import com.bigdate.threetier_architecture.dao.impl.EmpDaoA;
import com.bigdate.threetier_architecture.pojo.Emp;
import com.bigdate.threetier_architecture.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
//交给ioc容器处理 控制反转 称为ioc容器中的bean
@Component
public class EmpServiceA implements EmpService {
@Autowired//程序在运行时 ioc会提供该类型的bean对象 并赋值给该对象 依赖注入
private EmpDao empDao;
@Override
public List<Emp> listEmp() {
List<Emp> empList=empDao.listEmp();
empList.stream().forEach(emp -> {
//处理gender
String gender=emp.getGender();
if(gender.equals("1")){
emp.setGender("男");
}else emp.setGender("女");
//处理job
String job=emp.getJob();
if(job.equals("1")){
emp.setJob("学生");
}else emp.setJob("老师");
});
return empList;
}
}
java
package com.bigdate.threetier_architecture.controller;
import com.bigdate.threetier_architecture.pojo.Emp;
import com.bigdate.threetier_architecture.pojo.Result;
import com.bigdate.threetier_architecture.service.EmpService;
import com.bigdate.threetier_architecture.service.impl.EmpServiceA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class Controller {
@Autowired//程序在运行时 ioc会提供该类型的bean对象 并赋值给该对象 依赖注入
private EmpService empService;
@RequestMapping("/listEmp")
public Result list(){
//调用service响应数据 再响应数据
List<Emp> empList=empService.listEmp();
//响应数据
return Result.success(empList);
}
}
IOC详解
概念
控制反转
将对象的容器交给IOC容器 由IOC容器创建管理这些对象
而IOC容器里这些对象又是bean对象
Component注解可以适用于一些工具类
实操
我们之前开发的后端架构其实就已经交给IOC容器管理
注解RestController
启动Springboot
Component的衍生注解 底层都封装了原注解和Component
bean容器默认是类名小写
Bean的声明
Bean的组件扫描
把数据层移出去 运行就会报错 因为找不到bean了
这里有个隐式注解
启动类当前包以及子包 搭建架构的常见错误
我们要加注解
这种解决方案不规范
我们在实际开发中应该按照springboot的规范来书写代码
启动类是放在总工程包下
而于启动类同级的是不同业务层的包 里面有接口和实现类
小结
DI详解
依赖注入
IOC容器要为运行程序提供需要的资源 资源即对象
自动装配
会去IOC容器中自动找这种类型的对象
然后赋值给对象
如果说往IOC容器里放入了两个同类型的对象
依赖注入时就会报错
解决
Primary注解
设置优先级
Autowired+Qualifier注解
指定bean的名字
如果说声明bean的时候默认没有设置
那就是类名小写
Resource注解
Autowired是按照类型注入的
而Resource是按照名称注入的
小结
面试题
@Resource
和 @Autowired
是 Java 中用于依赖注入的注解,它们的主要区别如下:
-
来源:
@Resource
是 Java EE 提供的注解,在javax.annotation
包中。@Autowired
是 Spring Framework 提供的注解,在org.springframework.beans.factory.annotation
包中。
-
用途:
@Resource
旨在通过名称进行依赖注入。它默认按照名称进行匹配,如果指定了name
属性,则按照指定名称进行匹配。@Autowired
旨在通过类型进行依赖注入。它默认按照类型进行匹配,如果多个匹配项,则会尝试按照名称进行匹配。
-
配置:
@Resource
可以通过name
属性指定要注入的 Bean 的名称,也可以直接应用在字段、setter 方法或构造方法上。@Autowired
可以应用在字段、构造方法、setter 方法上,通过类型匹配自动注入 Bean。
-
依赖性:
@Resource
是 Java EE 的标准注解,不依赖于 Spring,可以在非 Spring 容器中使用。@Autowired
是 Spring 特有的注解,依赖于 Spring 框架,需要在 Spring 容器中才能生效。
总体而言,如果你想按照名称进行注入,可以使用 @Resource
;如果你想按照类型进行注入,并且在 Spring 环境中使用,通常会选择 @Autowired
。