目录
一、存储Bean
1.1 配置扫描路径
1.2 使用注解存储Bean对象
1.2.1 五大类注解
1.2.2 方法注解@Bean
二、获取Bean
2.1 属性注入
2.2 setter注入
2.3 构造方法注入
2.4 @Resource注解
2.5 同一类型多个Bean报错
一、存储Bean
在xml时代,存储一个Bean对象需要在配置文件中添加一行bean注册内容,而在当前的注解时代,我们只需要通过一个注解就可以完成Bean对象的存储和获取。
1.1 配置扫描路径
在使用注解来存、取Bean对象之前,先需要配置一下扫描路径,被配置路径下的类才可以被正确识别并存储到Spring中。
复制以下内容到spring配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:content="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<content:component-scan base-package="com.bit"></content:component-scan>
</beans>
base-package属性的内容就是需要填写的扫描路径 ,当前我的扫描根路径是com.bit,也就是说bit这个包底下的所有类,都可以被扫描到。
添加扫描根路径是为了提高程序的效率,比如我们使用杀毒软件进行杀毒时,会有全盘扫描和指定目录扫描,指定目录扫描的速度显然比全盘扫描更快,而此处添加的扫描根路径就相当于指定目录扫描~
1.2 使用注解存储Bean对象
存储Bean对象可以通过五大类注解或方法注解来实现:
1.2.1 五大类注解
五大类注解分别是:@Controller @Service @Respository @Configuration @Component
使用方法很简单,在想要存入的Bean对象所在的类上面添加上述五个注解中的任意一个即可,例如:
Spring就会根据根扫描路径,把扫描路径下带有以上注解的类的一个对象存入到Spring中。
五大类注解的用途
既然上述每个类注解都可以将Bean对象存入到Spring中,那么为什么要存在这么多的注解呢?
因为每个类注解所表示的含义不同,当程序猿看到类注解后,就可以知道当前类的用途:
@Controller(控制器):归属于业务逻辑层,用来控制用户的行为,检查请求的有效性,类似于安检;
@Service(服务):归属于服务层,调用持久化类实现相应的功能。不直接和数据库交互,类似于控制中心。
@Respository(仓库):归属于持久层,直接和数据库进行交互,通常每个表对应一个@Respository。
@Configuration(配置):归属于配置层,用来配置当前项目的一些信息。
@Component(组件):归属于公共工具类,提供某些公共方法。
五大类注解的关系:
查看每个注解的源码可以发现,每个注解中都有@Component注解,说明它们四个是@Component的“子类”。
Bean命名规则:
通过上述类注解可以成功地把Bean存储到Spring中,但是当我们从Spring中取对象时就尬住了,此处的Bean对象名填什么呢?
通常情况下,我们的类名都是大驼峰的命名方式,在读取Bean对象时,只需要小写首字母即可;如果类名的前两个字母都大写的话,需要使用原类名来读取Bean对象。
这样就可以成功从Spring中读取到user对象了:
Bean对象的命名规则源码(来自于JDK Introspector中的decapitalize方法):
1.2.2 方法注解@Bean
方法注解是添加在方法上的,添加了@Bean注解的方法中返回的对象就会被存储到Spring中,但是要注意,方法注解需要配合类注解使用,否则无法正确地存储和获取Bean对象:
此时,Spring中就会存储一个user对象。
重命名Bean对象:
可以使用@Bean注解中的name属性,来给Bean对象进行重命名:
name属性本身是一个String类型的数组,可以同时有多个名字。
注意:如果使用name属性重命名Bean后,那么使用小写类名首字母的方式就无法再获取到Bean对象。
二、获取Bean
获取Bean对象也叫做对象装配、对象注入,就是把存储到Spring中的对象取出来放到某个类中。
对象注入的方式有三种:
2.1 属性注入
实现方式:在属性/字段上方添加@Autowired注解
优点:属性注入最大的优点就是实现简单,并且使用简单。
缺点:
(1) 不能注入不可变对象(final修饰的对象);
(2) 只适用于IoC容器,通用性不好;
(3) 容易违背单一设计原则。
2.2 setter注入
实现方式:在属性/字段对应的set方法上方添加@Autowired注解
优点:更符合单一设计原则,每个set方法对应一个对象。
缺点:
(1) 不能注入不可变对象;
(2) 注入的对象更容易被修改(因为set方法是public修饰的,所以被注入的对象可能会被随时修改)
2.3 构造方法注入
实现方式:在构造方法上方添加@Autowired注解
优点:
(1) 可以注入不可变对象,final修饰的对象可以在构造方法中进行赋值;
(2) 注入的对象不会被修改,构造方法只有在创建对象时执行一次,所以被注入的对象不会被随意修改;
(3) 通用性更好,构造方法注入可以适用于任何框架。
2.4 @Resource注解
在进行属性注入和setter注入时,除了使用@Autowired注解外,还可以使用@Resource注解进行注入:
@Autowired 和 @Resource 的区别:
(1) @Autowired来自于Spring;@Resource来自于JDK。
(2) @Resource支持更多的参数设置,例如name。
(3) @Resource只能用于属性注入、setter注入,不能用于构造方法注入。
2.5 同一类型多个Bean报错
当我们往Spring中存入多个相同类型的Bean后,尝试获取Bean对象时就会报错:
报错信息表示,Bean对象不是唯一的。
解决方案:
(1) 使用@Bean注解的name属性给Bean对象进行重命名,然后使用@Resource注解的name属性获取指定名称的Bean对象。
(2) 使用@Bean注解的name属性给Bean对象进行重命名,使用@Qualifier注解的value属性获取指定名称的Bean对象。