文章目录
- 一. 应用分层
- 二. Spring IoC
- 获取String中的对象
- 五大 类注解
- 1. @Controller (控制器存储)
- 2. @Service(服务存储)
- 3. @Repository(仓库存储)
- 4. @Conponent(组件存储)
- 5. @Configuration(配置存储)
- 方法注解@Bean
- 定义多个对象
- 重命名
- 三. Spring DI
- 属性注入
- 构造方法注入
- Setter注入
- @Autowired存在的问题
一. 应用分层
Spring MVC, 就是把整体的系统分成了 **Model(模型), View(视图)和Controller(控制器)**三个层次,也就是将⽤⼾视图和业务处理隔离开,并且通过控制器连接起来,很好地实现了表现和逻辑的解耦,是⼀种标准的软件分层架构
而⽬前现在更主流的开发⽅式是 “前后端分离” 的⽅式, 后端开发⼯程师不再需要关注前端的实现, 所以对于Java后端开发者, ⼜有了⼀种新的分层架构: 把整体架构分为控制层(Controller)、业务逻辑层(Service)和数据层(Dao). 这种分层⽅式也称之为"三层架构"
二者的关系:
应用分层的好处:
• 降低层与层之间的依赖, 结构更加的明确, 利于各层逻辑的复⽤
• 开发⼈员可以只关注整个结构中的其中某⼀层, 极⼤地降低了维护成本和维护时间
• 可以很容易的⽤新的实现来替换原有层次的实现
• 有利于标准化
二. Spring IoC
我们在应用分层之后, 我们如果要用其他类的方法, 就需要创建这个类对象, 然后才能通过对象调用方法
IoC: Inversion of Control (控制反转)
Spring 是包含了众多⼯具⽅法的 IoC 容器
也就是说 Spring 是⼀个"控制反转"的容器, 反转的是对象的控制权
在使用某个类时, 我们可以通过IoC的思想, 将这个类交给Spring, 那么Spring就会帮我们创建这个类对象(Bean)
获取String中的对象
这时创建项目时, 默认创建的启动类, 用@SpringBootApplication标识
项目运行时, 会从这个启动类开始扫描, 扫描的范围就是这个类所在的包和子包
因为@SpringBootApplication这个注解, 包含了@ComponentScan
这个注解就标识了需要扫描的包的路径, 默认就是@SpringBootApplication所在的路径
如果需要扫描特定的路径, 可以通过@ComponentScan来修改
如果没有被Spring扫描到, 那么下面的IoC和DI 都不会起作用的
我们可以接收这个返回值, 使用getBean方法拿到Spring框架中的对象
目前, 我们可以通过三种方式获得Spring中的对象
- 通过类对象
- 通过对象名
对象名在Spring标准中, 默认规定:
如果类名采用大驼峰的方式命名, 那么对象名就是把大驼峰改成小驼峰
如果类名前两个字母都是大写, 那么对象名就是类名 - 通过对象名和类对象
想要把类对象交给Spring创建, 需要用注解来标识
五大 类注解
1. @Controller (控制器存储)
@Controller相当于是一个接口, @Controller标识的类, 通常是控制器, 用来和前端进行交互, 这时其他注解所不具备的功能
通过三种方式来获取对象
运行结果:
发现, 获取成功, 而且获取的都是同一个对象
说明: Spring创建的是单例对象
2. @Service(服务存储)
3. @Repository(仓库存储)
4. @Conponent(组件存储)
5. @Configuration(配置存储)
为什么要这么多注解?
这个也是和咱们前⾯讲的应⽤分层是呼应的. 让程序员看到类注解之后,就能直接了解当前类的⽤途.
• @Controller:控制层, 接收请求, 对请求进⾏处理, 并进⾏响应.
• @Servie:业务逻辑层, 处理具体的业务逻辑.
• @Repository:数据访问层,也称为持久层. 负责数据访问操作
• @Configuration:配置层. 处理项⽬中的⼀些配置信息
注解之间的关系:
其他所有的类, 都包含了@Component注解, 其余四个注解, 都是@Component的衍生注解, 也就是说, 其他的注解, 都可以使用@Component来代替, @Component是个"万能注解"(但是不能代替@Controller), 但并不建议这个做, 建议按照规范使用
方法注解@Bean
方法注解要搭配类注解使用才能生效
方法注解就相当于把我们创建好的这个对象, 交给Spring容器
可以通过类对象的方式拿到对象, 也可以通过对象名的方式拿到对象
此时, 对象名就是方法名
定义多个对象
那么, 就可以通过这种方式, 将多个类对象交给Spring
通过方法名区分不同对象:
重命名
如果想要更换对象名, 也可以通过:
或定义多个名字:
三. Spring DI
依赖注⼊是⼀个过程,是指IoC容器在创建Bean时, 去提供运⾏时所依赖的资源,⽽资源指的就是对象
简单来说, 就是把对象取出来放到某个类的属性中
使用**@Autowired注解**实现
属性注入
我们要将 Service 类注⼊到 Controller 类中
先确保Service对象在容器中
将 Service 类注⼊到 Controller 类中
如果注入成功, 那么就会打印service的sayHi
那么, Controller就拿到了Service的对象
构造方法注入
注意事项:
如果类只有⼀个构造⽅法,那么 @Autowired 注解可以省略, 因为当构造UserController对象时, 会自动在Spring中搜索UserService对象
如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法, 因为Spring创建对象默认调用无参构造函数
Setter注入
三种注⼊优缺点分析
@Autowired存在的问题
当同一类型的Bean存在多个时, 使用@Autowired会存在问题
报错的原因是, 非唯一的Bean对象
共有四种解决方案:
** 1. @Primary**
被@Primary标注的Bean, 表示默认的对象, 当多个同类型对象存在时, 默认注入这个对象
2. @Qualifier
@Qualifier必须搭配@Autowired使用, 指定要注入的Bean对象的名称
3. 命名时直接使用Bean对象的名称
4. @Resourse
@Resourse 是JDK提供的注入注解, 同样可以进行注入
注入时, 指定注入对象的名称
注入Bean的流程:
常见面试题:
@Autowird 与 @Resource的区别
• @Autowired 是spring框架提供的注解,⽽@Resource是JDK提供的注解
• @Autowired 默认是按照类型注⼊,⽽@Resource是按照名称注⼊. 相⽐于 @Autowired 来说, @Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。