Defaults to {@code true}.
*/
boolean required() default true;
}
```
示例:
```java
// 测试类 1
@SpringBootTest(classes = Application03.class)
@RunWith(SpringRunner.class)
// 引用配置 AutowiredConfig01
@Import(AutowiredConfig01.class)
public class AutowiredTest01 {
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* 默认按类型查找,存在多个相同类型的组件,查找到多个
* 抛异常:No qualifying bean of type 'com.onde.annotation.bean.User' available: expected single matching bean but found 2: autowired_user01,autowired_user02
*/
// @Autowired
private User user01;
/**
* 设定组件装配为非必须,但容器中确实存在类型为 User.class 的组件:autowired_user01、autowired_user01
* 此时依旧存在异常:No qualifying bean of type 'com.onde.annotation.bean.User' available:
expected single matching bean but found 2: autowired_user01,autowired_user02
*/
// @Autowired(required = false)
private User user02;
/**
* 若通过 @Qualifier("id") 指定需要装配组件的 ID,而不是使用类型装配,组件正常装配,注入组件:autowired_user01
*/
@Autowired
@Qualifier("autowired_user01")
private User user03;
/**
* 注入一个不在扫描规则内的组件(容器中不存在该组件)
* 此时将产生异常:No qualifying bean of type 'com.onde.annotation.service.AnnotationService' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true)}
*/
// @Autowired
private AnnotationService annotationService01;
/**
* 注入一个不在扫描规则内的组件(容器中不存在该组件),且设置该组件为非必须
* 此时无异常,但装配的是 null
*
*/
@Autowired(required = false)
private AnnotationService annotationService02;
@Test
public void test01() {
// 异常
System.out.println(user01);
}
@Test
public void test02() {
// 异常
System.out.println(user02);
}
@Test
public void test03() {
// 输出:User{id=60001, name='autowired_user01', age=20}
System.out.println(user03);
}
@Test
public void test04() {
// 异常
System.out.println(annotationService01);
}
@Test
public void test05() {
// 无异常,但装配的是 null
System.out.println(annotationService02);
}
}
```
```java
// 测试类 2
@SpringBootTest(classes = Application03.class)
@RunWith(SpringRunner.class)
// 引用配置 AutowiredConfig02
@Import(AutowiredConfig02.class)
public class AutowiredTest02 {
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* autowired_user01 组件中存在 @Primary 注解,为首选装配对象
* 此时无异常,装配的组件为:autowired_user01
*/
@Autowired
private User user;
@Test
public void test01() {
// 输出:User{id=60001, name='autowired_user01', age=20}
System.out.println(user);
}
}
```
示例配置AutowiredConfig03:
```java
// Bean 配置
@Configuration
// 配置只扫描 AutowiredConfig03.class
@ComponentScan(basePackages = "com.onde.annotation.config.autowired", includeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {AutowiredConfig03.class})
}, useDefaultFilters = false)
public class AutowiredConfig03 {
@Bean
public User autowired_user03() {
User user = new User();
user.setId(60003);
user.setName("autowired_user03");
user.setAge(20);
return user;
}
@Bean
public User autowired_user04() {
User user = new User();
user.setId(60004);
user.setName("autowired_user04");
user.setAge(20);
return user;
}
/**
* 注册 LoginInfo 对象
* @Autowired 标注在方法参数上,结合 @Bean 使用,用于自动装配容器中的对象,此处自动装配 autowired_user03 对象
*/
@Bean
public LoginInfo loginInfo(@Qualifier("autowired_user03") @Autowired User user) {
LoginInfo loginInfo = new LoginInfo();
loginInfo.setUser(user);
return loginInfo;
}
}
```
```java
@Service
public class UserService {
private User user01;
private User user02;
public UserService(@Qualifier("autowired_user03") User user01,
@Qualifier("autowired_user04") User user02) {
this.user01 = user01;
this.user02 = user02;
}
/**
* @Autowired 标注在构造器上,则参数列表会进行自动装配
* 如果组件只有一个有参构造器,这个有参构造器的 @Autowired 可以省略,此处有参构造器有两个所以不可省略
*/
@Autowired
public UserService(@Qualifier("autowired_user03") User user01) {
this.user01 = user01;
this.user02 = null;
}
public User getUser01() {
return user01;
}
public User getUser02() {
return user02;
}
/**
* user02 通过构造器赋空值
* @Autowired 标注在方法上,参数列表的 User 对象将自动装配为 autowired_user04
*/
@Qualifier("autowired_user04")
@Autowired
public void setUser02(User user02) {
System.out.println("user02: " + this.user02);
this.user02 = user02;
}
}
```
```java
// 测试类 3
@SpringBootTest(classes = Application03.class)
@RunWith(SpringRunner.class)
// 引用配置 AutowiredConfig03 和 UserService
@Import({AutowiredConfig03.class, UserService.class})
public class AutowiredTest06 {
/**
* @Autowired 标注在属性上
*/
@Autowired
private UserService userService;
/**
* @Autowired 标注在属性上
*/
@Autowired
private LoginInfo loginInfo;
@Test
public void test01() {
// 输出:
// User{id=60003, name='autowired_user03', age=20}
// User{id=60004, name='autowired_user04', age=20}
// LoginInfo(user=User{id=60003, name='autowired_user03', age=20})
System.out.println(userService.getUser01());
System.out.println(userService.getUser02());
System.out.println(loginInfo);
}
}
```
#### 7.2、@Resource
java JSR250 规范,@Resource 注解同样也可用于组件装配:
- @Resource 存在两个属性 name 和 type,可指定按类型装配(Bean Class)或者按名称装配(Bean ID)
- 不指定 name 或者 type 默认按名称装配(Bean ID)
- 不支持 @Primary 注解
- 组件必须在容器中存在,否则抛异常
示例:
```java
// 测试类 1
@SpringBootTest(classes = Application03.class)
@RunWith(SpringRunner.class)
// 引用配置 AutowiredConfig01,注入 AnnotationService
@Import({AutowiredConfig01.class, AnnotationService.class})
public class AutowiredTest03 {
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* 默认按 ID 查找,通过 user01 查找不到
* 抛异常:No qualifying bean of type 'com.onde.annotation.bean.User' available: expected single matching bean but found 2: autowired_user01,autowired_user02
*/
// @Resource
private User user01;
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* 指定 ID 查找,通过 autowired_user01 查找并注入,正常装配
*/
@Resource(name = "autowired_user01")
private User user02;
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* 默认按 ID 查找,通过 autowired_user02 查找并注入,正常装配
*/
@Resource
private User autowired_user02;
/**
* 容器中存在类型为 User.class 的组件有两个:autowired_user01、autowired_user01
* 指定类型查找,查找到多个组件
* 抛异常:No qualifying bean of type 'com.onde.annotation.bean.User' available: expected single matching bean but found 2: autowired_user01,autowired_user02
*/
// @Resource(type = User.class)
private User user04;
/**
* 容器中存在类型为 AnnotationService.class 的组件只有一个:com.onde.annotation.service.AnnotationService
* 未指定 ID 或者 类型,默认先按 ID 查找,再按类型查找
* 指定 ID 查找,通过 annotationService_01 查找不到
* 抛异常:No bean named 'annotationService_01' available
*/
// @Resource(name = "annotationService_01")
private AnnotationService annotationService_01;
@Test
public void test01() {
// 异常
System.out.println(user01);
}
@Test
public void test02() {
// 输出:User{id=60001, name='autowired_user01', age=20}
System.out.println(user02);
}
@Test
public void test03() {
// 输出:User{id=60001, name='autowired_user02', age=20}
System.out.println(autowired_user02);
}
@Test
public void test04() {
// 异常
System.out.println(user04);
}
@Test
public void test05() {
// 异常
System.out.println(annotationService_01);
}
}
```
#### 7.3、@Inject
java JSR330 规范,@Inject 与 @Autowired 类似,可以完全代替 @Autowired,但没有 required 属性要求 Bean 必须存在
- 默认按照类型(class)去容器中找对应的组件
- 如果存在多个相同类型的组件,则需要将属性的名称作为组件的 ID 再去容器中查找
- 可通过 @Qualifier("id") 指定需要装配组件的 ID,而不是使用类型装配
- 或者通过 @Primary 注解指定自动装配时的首选 Bean
- 需引入 javax.inject 依赖
```xml