新手小白记录跟着狂神学Spring的过程(第12-13集)~
1.bean的自动装配
自动装配的原理是基于byName和byType的。
1.1 byName自动装配
会自动在容器中查找,和自己对象set方法后面的值对应的bean id。所以bean的id要全局唯一并且和属性名一致。
<bean id="cat" class="com.pojo.Cat"/>
<bean id="user" class="com.pojo.User" autowire="byName">
<property name="school" value="scnu"/>
<!-- 省略了<property name="cat" ref="cat"/> -->
</bean>
User user = context.getBean("user",User.class);
user.getCat.shout();
会输出:miao~
证明自动装配成功!
1.2 byType自动装配
会自动在容器上下文中,根据bean的class,查找和对象属性类型相同的bean(用byType自动装配可以无需bean的id)。
弊端:不能出现class相同的两个bean,否则会报错。
<!-- 这里的id没起到作用,甚至可以不写id-->
<bean id="dog1111" class="com.pojo.Dog"/>
<bean id="user" class="com.pojo.User" autowire="byType">
<property name="name" value="Zoe"/>
<!-- 省略了<property name="dog" ref="dog1111"/> -->
</bean>
User user = context.getBean("user",User.class);
user.getDog.shout();
会输出:wang~
证明自动装配成功!
1.3 使用注解实现自动装配
首先,导入约束,然后添加对注解的支持。
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 开启注解的支持 -->
<context:annotation-config/>
<!-- 配置文件变得非常简洁,只需写bean的id和class -->
<bean id="cat" class="com.pojo.Cat"/>
<bean id="dog" class="com.pojo.Dog"/>
<bean id="user" class="com.pojo.User"/>
</beans>
@Autowired
- 在类里面添加注解@Autowired,自动注入bean。默认先按
byType查找,找不到则报错,找到多个就按byName查找。直接在属性上添加注解,也可以在set方法上使用。使用@Autowired可以不编写set方法,前提是自动装配的属性在IoC容器(也就是Spring容器)中存在,且名字相同。
public class User{
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
//以下省略get和set方法……
}
- 如果显式地定义了
@Autowired(required = "false"),说明这个对象可以为null,否则不允许为空 - 如果@Autowired 自动装配的环境比较复杂,例如同一个类有多个bean,我们可以使用
@Qualifier(value = "xxx")来配合@Autowired 的使用,从而指定唯一的bean。
<bean id="cat" class="com.pojo.Cat"/>
<bean id="dog11" class="com.pojo.Dog"/>
<bean id="dog22" class="com.pojo.Dog"/>
<bean id="user" class="com.pojo.User"/>
public class User{
@Autowired
private Cat cat;
@Autowired
@Qualifier(value = "dog22")
private Dog dog;
private String name;
//以下省略get和set方法……
}
@Resource
默认先通过byName寻找,可以指定bean的id @Resource(name = "dog11");
如果找不到名字,就通过byType寻找(此时根据byType的原则,在Spring容器中,目标类型必须有且仅有一个,否则报错)
<bean id="cat" class="com.pojo.Cat"/>
<bean id="dog11" class="com.pojo.Dog"/>
<bean id="dog22" class="com.pojo.Dog"/>
<bean id="user" class="com.pojo.User"/>
public class User{
@Resource
private Cat cat;
@Resource(name = "dog11")
private Dog dog;
private String name;
//以下省略get和set方法……
}
@Resource和@Autowired的区别:
| @Autowired | @Resource | |
|---|---|---|
| 实现方式 | 先 byType,后 byName(byType 为基础) | 先 byName,后 byType(byName 为基础) |
| 名称指定方式 | 需配合 @Qualifier 注解 | 直接通过 name 属性指定 |
| 支持泛型注入 | 支持(如 List<UserService>) | 不支持 |
补充:@Autowired 支持泛型注入的场景
// 泛型接口
public interface BaseService<T> {}
// 实现类1(泛型类型:User)
@Service
public class UserService implements BaseService<User> {}
// 实现类2(泛型类型:Order)
@Service
public class OrderService implements BaseService<Order> {}
// 注入:按泛型类型(BaseService<User>)匹配,找到唯一UserService
@Autowired
private BaseService<User> userBaseService;