三层架构
分析见:
分层解耦
内聚:软件中各个功能模块内部的功能联系
耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
软件设计原则:高内聚低耦合。
- 高内聚指的是:一个模块中各个元素之间的联系的紧密程度,如果各个元素(语句、程序段)之间的联系程度越高,则内聚性越高,即 "高内聚"。
- 低耦合指的是:软件中各个层、模块之间的依赖关联程序越低越好。
高内聚、低耦合的目的是使程序模块的可重用性、移植性大大增强。
![](https://i-blog.csdnimg.cn/direct/ab7ba5ec4ed74ac09fb6616b7b14937d.png)
控制反转:
Inversion Of Control
,简称
IOC
。对象的创建控制权由程序自身转移到外部
(容器),这种思想称为控制反转
对象的创建权由程序员主动创建转移到容器
(
由容器创建、管理对象
)
。这个容器称为:
IOC
容器或
Spring
容器
依赖注入:
Dependency Injection
,简称
DI
。容器为应用程序提供运行时,所依赖的资源,
称之为依赖注入。
程序运行时需要某个资源,此时容器就为其提供这个资源。
例:
EmpController
程序运行时需要
EmpService
对象,
Spring
容器就为其提供并注入
EmpService
对象
IOC
容器中创建、管理的对象,称之为:
bean对象
三层代码解耦(Controller层、Service层、Dao层)
1.
删除
Controller
层、
Service
层中
new
对象的代码
2. Service
层及
Dao
层的实现类,交给
IOC
容器管理
3.
为
Controller
及
Service
注入运行时依赖的对象
- Controller程序中注入依赖的Service层对象
- Service程序中注入依赖的Dao层对象
![](https://i-blog.csdnimg.cn/direct/e1bba2e8b8d547a083bf6c30fd3c5cef.png)
使用
Spring
提供的注解:
@Component
,就可以实现类交给
IO
![](https://i-blog.csdnimg.cn/direct/eaa14840d68f4ce3ae4d5409237c2888.png)
@Component //将当前类交给IOc容器管理,成为IOC容器中的bean
@Autowired
//
运行时
,
从
IOC
容器中获取该类型的bean对象
,
赋值给该变量----依赖注入
IOC
Bean的声明
要把某个对象交给
IOC
容器管理,需要在对应的类上加上如下注解之一:
注解 | 说明 | 位置 |
@Controller
|
@Component
的衍生注解
|
标注在控制器类上
|
@Service
|
@Component
的衍生注解
|
标注在业务类上
|
@Repository
|
@Component
的衍生注解
|
标注在数据访问类上(由于与
mybatis
整合,用的
少)
|
@Componen
|
声明
bean
的基础注解
|
不属于以上三类时,用此注解
|
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
使用四大注解声明的
bean
,要想生效,还需要被组件扫描注解
@ComponentScan
扫描
- @ComponentScan注解虽然没有显式配置,但是实际上已经包含在了引导类声明注解
- @SpringBootApplication 中, 默认扫描的范围是SpringBoot启动类所在包及其子包
如果不在同一目录下则报错找不到bean对象。
解决方案:
①手动添加@ComponentScan注解,指定要扫描的包
②推荐做法:
将我们定义的
controller
,
service
,
dao
这些包呢,都放在引导类所在包
com.itheima
的子
包下,这样我们定义的
bean
就会被自动的扫描到
![](https://i-blog.csdnimg.cn/direct/b2ba068d62604589a61af956355525fd.png)
DI
我们使用了
@Autowired
这个注解,完成了依赖注入的操作,而这个
Autowired
翻译过来叫:自动装配。
@Autowired
注解,默认是按照
类型
进行自动装配的(去
IOC容器中找某个类型的对象,然后注入操作)
入门程序举例:在
EmpController
运行的时候,就要到
IOC
容器当中去查找
EmpService
这个类
型的对象,而我们的
IOC
容器中刚好有一个
EmpService
这个类型的对象,所以就找到了这个类型
的对象完成注入操作。
那如果在
IOC
容器中,存在多个相同类型的
bean
对象,会报错
![](https://i-blog.csdnimg.cn/direct/f096c293e8d840eb81aa581c04fcbbea.png)
解决问题
①@Primary
当存在多个相同类型的Bean注入时,加上@Primary注解,来确定默认的实现。
②@Autowired + @Qualifier
指定当前要注入的
bean
对象。 在
@Qualifier
的
value
属性中,指定注入的
bean
的名称
@Qualifier
注解不能单独使用,必须配合
@Autowired
使用
![](https://i-blog.csdnimg.cn/direct/4d3f19a1618d490983b48f0e06c2cf47.png)
③@Resource
是按照bean的名称进行注入。通过name属性指定要注入的bean的名称。
@Autowird
与
@Resource
的区别:
- @Autowired 是spring框架提供的注解,而@Resource是JDK提供的注解
- @Autowired 默认是按照类型注入,而@Resource是按照名称注入