IOC/DI学习
@Controller
作用:接收请求,处理响应。
@ResponseBody
类型:方法注解、类注解上面均可
作用:将方法的返回值直接响应,如果返回值的类型是实体对象、集合,将会转为JSON格式响应。
@RestController = @Controller + @ResponseBody
1 | |
数据访问 ===> 解析XML文件
逻辑处理 ===> 将前端页面的一些数据进行合理转换
接收请求,响应数据===> retrun
在进行软件设计的时候类或者方法职责尽可能单一。更利于后期的维护。
三层架构
Controller:控制层,接收前端发送过来的请求,对于其进行处理,并响应数据。
1 | |
service:业务逻辑层,处理具体的业务逻辑。
1 | |
dao:数据访问层(持久层),负责数据的访问操作,包括数据的增删改查。
1 | |
前端发起请求之后,首先会到达Controller层(controller接收到请求之后,要去调用Service进行逻辑处理,得先拿到数据,service层要去调用Dao层,dao层再去操作文件当中的数据,将数据拿到之后,再将数据返回给Service,service拿到数据之后,在进行逻辑处理。再将逻辑处理的结果返回给Controller)controller再给前端响应数据。
Dao层访问文件当中的数据、数据库中的数据、抑或是别人给了一个接口获取的数据,实现的方式有很多,可以面向接口编程,增强程序的灵活性。
Service 层也是类似,面向接口编程。
分层解耦
内聚:软件中各个功能模块内部的功能联系。
耦合:衡量各个层/各个模块之间的关联程度的。
假如上述我们要切换上述Service的实现,将EmpServiceA切换为EmpServiceB,此时,Controller 的代码也得进行改动,我们需要将new的对象切换为EmpServiceB,所以,Service层与Contoller 层的代码耦合了。所以在conroller层取消new一个对象。(但是肯定对报错的)
如何解决上述问题呢?
提供一个容器(存储一些对象EmpServiceA、EmpServiceB……),如果我们(例如Controller)需要使用这些对象,只需要在容器当中查找这些对象,再将这些对象赋值给EmpService。
这里会有两个问题。
1、对象如何交给容器管理?
2、容器如何为程序提供所依赖的资源。
控制反转(IOC):对象创建程序的控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入(DI):容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象称之为bean。
需要完成的任务是Controller层与Service层代码的解耦,Service层与Dao层的代码的解耦。
①将Serveice 层以及DAO层的实现类,交给IOC容器管理。 ===> 需要交给IOC进行管理@component
1 | |
②为Controller层以及Service层运行注入的时候,依赖的对象。 ===> 需要加入@Autowired注解
1 | |
IOC详解
对象创建程序的控制权由程序自身转移到外部(容器),这种思想称为控制反转。
bean的声明:
要将某一个对象交给IOC容器进行管理,需要在对应的类上加上如下注解之一:
| 注解 | 说明 | 位置 |
|---|---|---|
| @Component | 声明bean的基础注解 | 不属于以下三类的时候,使用此注解。 |
| @Controller | @Component的衍生注解 | 标注在控制器的类上面 |
| @Service | @Component的衍生注解 | 标注在业务类上面 |
| @Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的比较少) |
- 在声明bean的时候,我们可以通过value 属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发的时候,声明控制器bean只能使用@Controller
这四个注解声明的bean就一定会生效吗?
涉及到一个bean的组件扫描的问题。
- 前面声明bean的四大注解,要想生效;还需要被组件扫描注解@componentScan扫描。
- @componentScan注解虽然没有显示配置,但是实际上已经包含在了启动类声明注解@SpringBootApplication之中,默认的扫描范围是启动类所在的包及其子包。
依赖注入DI详解
容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
@Autowired注解,默认是通过类型进行的,如果存在多个相同类型的bean,会出现报错。
- 通过以下的方式可以进行解决
@primary 用来设置bean的优先级
@Qualifier @Qualifier(“empServiceA”)
@Resource