目录
一、Spring的概念
Spring是包含了众多方法工具的IoC容器,包括Spring Boot、Spring MVC等,其核心思想为IoC,控制反转。
二、IoC概念
容器:在类上面添加@Controller等注解时,该类下的对象就交给了spring容器管理。启动类运行时就会加载该类,实现了把对象交给Spring容器管理。
IoC:控制反转。指获得依赖对象的过程被反转了。当需要某个对象时,传统建立对象是通过new类名创建对象,现在把创建对象的任务交给了spring容器管理,只需要依赖注入需要的对象即可,但依赖注入的对象要确保spring容器已经管理。
三、IoC优点
1、资源集中管理,需要使用时去容器中拿即可;
2、降低了使用资源双方的依赖程度,即耦合性。
四、DI概念
依赖注入,把从容器中拿到的对象注入到需要使用的对象中。
五、Bean概念
交由Spring管理的对象称为Bean。
六、IoC具体操作
1、Bean存储
当在类上添加某些注解时,就是将对象的控制权交给了spring的IoC容器,由IoC容器创建及管理对象。
2、两类注解可以实现Bean存储
(1)类注解:@Controller;@Service;@Repository;@Component;@Configuration;
(2)方法注解:@Bean
3、@Controller存储
(1)向Spring容器中存储
(2)从Spring容器中拿---根据类型拿
这是Spring的启动类,如何知道我们已经将userController类存储到容器中了。
可以将启动类修改为:
注意:
①上下文:指当前运行的环境,也可以看作是一个容器。
②获取上下文是ApplicationContext提供的方法;获取bean对象是ApplicationContext的父类BeanFactory提供的方法;
ApplicationContext VS BeanFactory :
BeanFactory提供了基础的访问容器的能力,ApplicationContext除了继承BeanFactory类的功能外,还具有独特的特性,还添加了对国际化支持、资源访问支持、已经事件传播等方面的支持。
(3)从Spring中拿---根据Bean名称拿
上面是根据类型(userController)来拿的bean对象,但若同一个类型有多个对象时,根据类型拿的话不知道拿哪个,这是也可以根据Bean名称来拿。
Bean名称:若没有显示的提供名称,Spring容器将会为bean对象生成唯一的名称。
Bean名称生成规则:当有多个字符并且第⼀个和第⼆个字符都是大写时,按原始名称保留;其他使用小驼峰命名。例如:userController的名称为:userController;USercontroller的名称为:USerController。
Bean作用举例:例如有一个接口Animal,有两个类Dog类和Cat类实现了Animal接口,若根据Animal类型去拿就会出现歧义,此时就可以根据bean名称具体拿某个Bean对象--dog去拿Dog类。
4、@Service存储
(1)向Spring容器中存储
(2)从Spring容器中拿
5、@Repository
(1)向Spring容器中存储
(2)从Spring容器中拿
6、@Component存储
(1)向Spring容器中存储
(2)从Spring容器中拿
7、@Configuration存储
(1)向Spring容器中存储
(2)从Spring容器中拿
8、@Bean存储
@Bean是方法存储,此时我们已经存在一个类,我们想获取到该类的对象,可以写一个方法获取该类对象,在该方法上加@Bean注解就将该对象存储到Spring容器中了。
定义的User类:
(1)向Spring容器中存储
(2)从Spring容器中拿
发现报错,spring容器中没有userBean对象。是因为刚刚我们只加入了方法注解,没有加入类注解,需要加入类注解。
(3)同一个User类,,存两个对象。
从spring中获取User对象:
报错有两个对象,不知道拿哪个对象。且方法注解中方法名就是bean名称。
根据bean名称取对象:
(4)重命名bean名称
9、扫描路径
使用注解将bean对象存到容器中不一定生效。
原始路径为:
修改路径为:
没有扫描到对应的bean对象,是因为没有规定扫描路径时,取bean对象时默认只扫描启动类所在包,其他包不扫描,导致取不到其他包里的bean对象。
指定扫描路径:
10、类注解之间的关系
发现上面四个注解源码一样,且都包含@Component注解。功能一样,但为什么有四个注解??
是因为给注解赋予了不同的概念,使得程序员看到注解就明白了当前类的用途。
@Controller:控制层,接收请求,对请求进行处理,并进行响应;
@Service:业务逻辑层,处理具体的业务逻辑;
@Repository:数据访问层,也称为持久层,负责数据访问操作;
@Configuration:配置层,处理项目中的一些配置信息;
七、DI具体操作
从容器中拿对象
1、属性注入
将userService类注入到userController类中:
2、构造方法注入
(1)一个构造方法
(2)多个构造方法
当有多个构造函数时,spring会默认使用无参构造函数,若没有这个构造函数会报错。以上调用了无参构造函数,但userservice对象未被注入,出现空。
使用@Autowried注解指定调用哪个构造函数:
3、Setter方法注入
4、三种注入方式优缺点
(1)属性注入
使用简单方便,但只能用于IoC容器,非IoC容器不能使用,不能注入finall修饰的属性。
(2)构造方法注入
可以注入finall修饰的属性,注入的对象不会被修改,注入繁琐。
(3)Setter方法注入
不能注入finall修饰的属性,注入的对象可以被修改。
5、解决@Autowired注解存在的问题
当一个类型存在多个对象时,注入对象会出现什么问题???
一个类型下两个对象:
注入到userController类中:
报错原因是不是唯一的bean对象。
解决方法:
(1)@Primary注解
当存在多个同类型bean对象时指定默认的bean对象
(2)@Qualifier注解
根据bean名称,指定要加入的对象。
(3)@Resource
根据bean名称指定要加入的对象。
(4)@Autowired vs @Resource
①@Autowired是spring框架提供的注解;@Resource是jdk提供的注解。
②@Autowired默认按照类型注入,匹配到一个就直接注入,若同一类型匹配到多个就按bean名称注入,名称没有查找到就报错;@Resource按照名称注入。