1、注入bean
当存在配置文件,且没有配置类时(@Configuration标注的类),注解生效需要配置context:annotation-config,也可以配置context:component-scan,它基于annotation-config的基础上添加base-package,include,exclude等属性,用于添加扫描包的条件。
当存在配置类时,需要在其上添加ComponentScan注解,配置base-package,include,exclude属性。含义与context:component-scan标签相同。
当注解存在name属性时,容器会将name属性值作为bean的名称,当不存在name属性时,会将类名的首字母作为bean的名称,需要特别注意的是类名不是包名,当不同包下存在相同类名时,会存在同名的bean。
Spring支持自定义bean名称的生成策略,两个步骤,第一步编写MyNameGenerator实现NameGenerator接口,第二步设置该类为Component-scan注解的name-generator属性值。
1.1 Configuration
描述 |
它用于创建AnnoationConfigApplicationContext,它属于配置类。地位等价于applicationContext.xml |
位置 |
类上 |
1.2 ComponentScan
描述 |
它用于指定容器注入bean时的一些配置。 |
属性 |
basePackage: 说明:指定扫描包的根路径,存在多个时,使用逗号分隔 类型:字符串,包名或者包名的正则表达式 是否必填:否,不指定时默认为classpath |
属性 |
Include-filter: 说明:添加包含的过滤条件,过滤条件有五种类型,
类型:不同类型对应不同的数值类型 是否必填:否,不指定时无过滤器 |
属性 |
enclude-filter: 说明:添加排除的过滤条件,过滤条件有五种类型,
类型:不同类型对应不同的数值类型 是否必填:否,不指定时无过滤器 |
属性 |
lazyInit: 说明:指定bean加载时是否延迟加载 类型:布尔值 是否必填:否,默认值为false。 |
属性 |
nameGenerator: 说明:指定bean注入时,名称的生成 类型:NameGenerator的实现类 是否必填:否。 |
位置 |
配置类上 |
1.3 Component
描述 |
它代表一个bean,当IOC容器扫描包时,会把标有该注解的类添加到容器中 |
位置 |
类上 |
1.4 Repository
描述 |
它是Component注解的元注解,功能与Component相等,含义缩小,只表示MVC层中的Model层,即DAO数据层 |
位置 |
类上 |
1.5 Service
描述 |
它是Component注解的元注解,功能与Component相等,含义缩小,只表示服务层 |
位置 |
类上 |
1.6 Controller
描述 |
它是Component注解的元注解,功能与Component相等,含义缩小,只表示控制器层 |
位置 |
类上 |
1.7 RestController
描述 |
它是Controller与ResponseBody的组合注解,表示它是一个Controller,并且响应类型为数据流。 |
位置 |
类上 |
1.8 bean
描述 |
它代表一个bean,标注在方法上,将该方法的返回值注入到IOC容器中。 |
属性 |
name: 说明:指定bean的名称,默认值为方法的名称,当指定多个name值时,本质是在设置bean的别名。 类型:字符串, 是否必填:否 |
属性 |
Init-method: 说明:对应bean标签的init-method属性。 类型:字符串,方法名称 是否必填:否,默认值为init, |
属性 |
destory-method: 说明:对应bean标签的destory-method属性。 类型:字符串,方法名称 是否必填:否,默认值为close,shutdown |
位置 |
方法上(居多),注解上 |
定义在@Configuration下的@Bean会通过CGLIB方式调用方法,并获取相关的原信息,所以方法不能使用private,final修饰。定义在@Component下的@Bean不会。
2、获取bean
2.1 Required(已废弃)
描述 |
在设置bean属性时,Required注解表示该属性为必备属性,如果在创建Bean时,没有对应的属性值,会抛出异常。构造器依赖也会起到同样的效果。 |
位置 |
属性上,或者属性的set方法上 |
2.2 AutoWired
描述 |
它对应bean标签的autowire属性,在注入bean的依赖时,从IOC容器中获取,获取方式有四种NONE,byName,byType,constructor。默认的方式为byName,如果查找不到,根据byType方式。 当属性为容器类型时,数组或集合时,会把找到的所有依赖都放入容器中 |
属性 |
required: 说明:当注入beanA的依赖beanB时,用于指定该依赖是否是必须的,当为true时,为必须的,此时容器中没有依赖的beanB,则beanA创建失败,并报错。 类型:布尔值,true或者false 是否必填:否,默认值为true |
位置 |
依赖的任何地方,属性上,构造器参数,方法参数 |
示例如下:
public class User { // 自动注入Address类,当IOC容器中没有Address时,User创建失败并报错 @Autowired(required=true) private Address homeAddress; }
2.3 Order
描述 |
当beanA依赖beanB的容器时,IOC容器在查找beanB时,如果beanB有多个,Order注解用来决定在容器中的顺序 |
位置 |
类上 |
示例如下:
public class User { // IOC中存在多个Address时,IOC会根据Order注解决定Address在List<Address> // 的顺序 @Autowired(required=true) private List<Address> homeAddress; } // Address类 @Order(value=1) public class Address { }
它一般发生在根据byName无法找到依赖时,根据byType查找时,存在多个相同的类名,例如上例中不存在id为homeAddress的bean,存在多个Address类,com.test.Address,com.bean.Address。
2.4 Primary
描述 |
当beanA依赖beanB的容器时,IOC容器在查找beanB时,如果beanB有多个,Primary用来指定优先使用该bean。 对应bean标签的primary属性 |
位置 |
注入bean时的任何地方,方法,类上 |
示例如下:
public class User { // IOC中存在多个Address时,IOC会根据Order注解决定Address在List<Address>的顺序 @Autowired(required=true) private Address homeAddress; } // Address类 @Component @Primary public class Address { }
与Order不同的是,beanA依赖beanB,它们之间的关系是1:1,而IOC容器中存在多个beanB,此时由于无法决定使用哪个beanB,导致beanA创建失败,primary用于决定优先选中哪个beanB。如果beanB只存在一个时,该注解无意义。
2.5 Qualifier
描述 |
当beanA依赖beanB,并且在容器中存在多个beanB时,Qualifiler注解用于为beanB分类。 |
位置 |
注入beanB时用来为beanB归类,获取时qualifier作为过滤条件,查找合适的beanB。 |
分类的方式有三种,
- 第一种,设置qualifier的value属性
- 注入Address类
<!-- 家庭住址 --> <bean class="com.bean.Address"> <qualifier value="homeAddress" /> </bean> <!-- 公司住址 --> <bean class="com.bean.Address"> <qualifier value="companyAddress" /> </bean>
2.获取Address
public class User { // 用户的家庭地址 @Autowired @Qualifier("homeAddress") private Address homeAddress; // 用户的工作地址 @Autowired @Qualifier("companyAddress") private Address companyAddress; }
此时Qualifier注解的作用与bean的ID差不多,还不如指定id属性,并且使用byName的方式获取
2.第二种,Qualifier的元注解
- 编写@HomeAddress,@CompanyAddress注解
/** * * @Title: HomeAddress.java * @Package com.annotation * @Description: HomeAddress注解 * @version V1.0 */ @Target({ElementType.FIELD,ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Qualifier public @interface HomeAddress { // 居住地址 String value(); }
2.注入Address类,配置qualifier子标签,可以看到子类相当于二级分类。
<bean class="com.bean.Address"> <qualifier type="com.annotation.HomeAddress" value="homeTown" /> </bean> <bean class="com.bean.Address"> <qualifier type="com.annotation.CompanyAddress" value="working" /> </bean>
3. 获取Address类
public class User { // 用户的家庭地址 @Autowired @HomeAddress("homeTown") private Address homeAddress; // 用户的工作地址 @Autowired @CompanyAddress("working") private Address companyAddress; }
此示例中,子类相当于二级目录,其中的value属性相当于过滤条件,如果value不是homeTown和working,则找不到Address类。homeAddress和companyAddress为null值
3.第三种,继承Qualifier,添加更多的属性值作为过滤条件,例如在上述示例中只有value作为过滤条件,可以在注解中添加其他属性。
它与第二种方式基本相同,在第二步时,注入Address类时,多个属性的格式为:
<bean class="com.bean.Address"> <qualifier type="com.annotation.HomeAddress"> <attribute key="field1" value="value1"/> <attribute key="field2" value="value2"/> </qualifier> </bean>
当beanA依赖beanB,并且存在多个beanB时,该注解为beanB分类,支持一级分类和二级分类。
当容器中只存在一个beanB时,该注解无任何意义
当只需要一级分类时,完全可以由bean的ID,name,alias等属性代替。
当需要二级分类时,可以使用该注解。
在实际的项目中,基本不会存在二级分类的情形,所以该注解的使用频率很低。
2.6 Resource(Java_based)
描述 |
当beanA依赖beanB时,Resource注解用于在IOC容器中查找beanB。方式通常是byName,当不指定name属性时,name的属性值为类名首字母小写。 |
属性 |
name: 说明:根据name在IOC中查找beanB,它对应beanB的ID,name,alias中的任意一个。 类型:字符串 是否必填:否,默认值为类名首字母小写 |
位置 |
属性上,属性的set方法上 |
示例如下:
- 第一步,注入Address
<bean id="address" class="com.bean.Address"/>
2. 第二步,获取
public class User { // 用户的工作地址,可以不指定,默认值也是address @Resource(name="address") private Address companyAddress; }
2.7 Inject(Java_based)
描述 |
等价于@Autowired |
2.8 Named
描述 |
当不指定value属性值时,等价于@Component,当指定value值时,等价于@Qualifier(“value”)。 |
2.9 Nullable (Java_based)
描述 |
等价于@Autowired(required=false) |
3、配置bean
3.1 Description
描述 |
Bean的一段描述文字 |
位置 |
方法上,与@Bean一起使用 |
3.2 Value
描述 |
用于获取Properties的值,并且把该值赋给对象的属性 |
属性 |
key: 说明:IOC容器中变量的key值,它可以从JVM变量,操作系统变量,配置文件等等获取。 类型:springEL表达式 是否必填:是 |
位置 |
属性上 |
3.3 LazyInit
描述 |
用于定义bean是否延迟加载 |
属性 |
value: 说明:true时延迟加载,false时随容器的创建加载。 类型:布尔值 是否必填:否,默认值为false |
位置 |
方法上,与@Bean一起使用 |
3.4 Scope
描述 |
用于指定bean的作用域, |
属性 |
value: 说明:bean作用域的值,五个值中的任意一个。 类型:枚举值,singleton,prototype,request,session,application 是否必填:否 |
位置 |
方法上,与@Bean一起使用 |
3.5 RequestScope
描述 |
等价于@Scope(“request”) |
3.6 SessionScope
描述 |
等价于@Scope(“session”) |
3.7 ServletContextScope
描述 |
等价于@Scope(“application”) |
3.8 PostConstruct(Java_based)
参考bean的生命周期,它添加在方法上,触发时机在构造器之后,init方法之前。
3.9 PreDestory(Java_based)
参考bean的生命周期,它添加在方法上,触发时机在bean的销毁阶段,destory方法之前。
3.10 Lookup
描述 |
对应bean的子标签lookup,用于解决singleton依赖prototype的问题。 |