一、学习目标
Spring的装配方式多种多样,这些方式旨在帮助开发者以灵活和高效的方式管理应用中的bean(即对象)。
二、bean的自动装配
1.spring的装配方式
1. XML配置方式
XML配置方式是通过XML文件来描述Bean的配置信息。开发者可以在XML文件中定义Bean的id、class、属性以及Bean之间的依赖关系等。Spring的BeanFactory或ApplicationContext会加载和解析这些配置文件,进而创建和管理Bean的实例。
2. 注解方式
注解方式是Spring装配的另一种重要方式。通过使用注解,开发者可以在类、方法或字段上直接声明Bean的装配信息,而无需编写繁琐的XML配置文件。如@Component
、@Repository
、@Service
、@Controller
等,这些注解用于标识类为Spring管理的组件
3. Java配置方式
Java配置方式允许开发者通过编写Java代码来定义Bean的配置信息。这种方式通常使用@Configuration
注解来标识一个配置类,并使用@Bean
注解来定义Bean的创建方法。通过这种方式,开发者可以摆脱XML配置的束缚,以更灵活的方式管理Bean。
4. 自动装配方式
自动装配是Spring提供的一种高级功能,它可以根据Bean之间的依赖关系自动完成Bean的装配。Spring支持多种自动装配的方式,包括根据类型(byType)、根据名称(byName)和根据构造函数参数(constructor)进行自动装配。开发者可以通过在配置文件中设置<bean>
标签的autowire
属性,或者在Java配置中使用@Autowired
注解来启用自动装配。
2.搭建测试环境
项目结构
实体类
public class person {
private friend friend;
private girlFriend girlFriend;
private String name;
public person() {
}
public person(com.lzh.pojo.friend friend, com.lzh.pojo.girlFriend girlFriend, String name) {
this.friend = friend;
this.girlFriend = girlFriend;
this.name = name;
}
public com.lzh.pojo.friend getFriend() {
return friend;
}
public void setFriend(com.lzh.pojo.friend friend) {
this.friend = friend;
}
public com.lzh.pojo.girlFriend getGirlFriend() {
return girlFriend;
}
public void setGirlFriend(com.lzh.pojo.girlFriend girlFriend) {
this.girlFriend = girlFriend;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("my friend is "+this.friend.getName());
System.out.println("my girlfriend is "+this.girlFriend.getName());
}
}
public class friend {
private String name;
public friend() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public friend(String name) {
this.name = name;
}
}
public class girlFriend {
private String name;
public girlFriend() {
}
public girlFriend(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
xml文件
<bean id="friend" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<bean id="girlFriend" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<bean id="person" class="com.lzh.pojo.person">
<property name="name" value="lzh"></property>
<property name="friend" ref="friend"></property>
<property name="girlFriend" ref="girlFriend"></property>
</bean>
3.byname
当使用byName
自动装配时,Spring容器会查找与需要被注入的bean的属性名相匹配的bean的id或name,并将其注入到该属性中。如果找不到匹配的bean,那么自动装配将会失败。
<bean id="friend" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<bean id="girlFriend" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<!--bean id="person" class="com.lzh.pojo.person">
<property name="name" value="lzh"></property>
<property name="friend" ref="friend"></property>
<property name="girlFriend" ref="girlFriend"></property>
</bean-->
<bean id="person" class="com.lzh.pojo.person" autowire="byName">
<property name="name" value="qinjiang"/>
</bean>
4.bytype
当使用byType
自动装配时,Spring容器会查看需要被注入的bean的属性类型,然后在容器中找到相同类型的bean进行注入。如果容器中存在多个相同类型的bean,那么这种自动装配方式将会失败,因为它无法确定应该注入哪一个bean。
<bean id="friend" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<bean id="girlFriend" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<!--bean id="person" class="com.lzh.pojo.person">
<property name="name" value="lzh"></property>
<property name="friend" ref="friend"></property>
<property name="girlFriend" ref="girlFriend"></property>
</bean-->
<bean id="person" class="com.lzh.pojo.person" autowire="byType">
<property name="name" value="qinjiang"/>
</bean>
测试
@Test
public void test1() {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
person person =(person) context.getBean("person");
person.show();
}
5.使用注解进行装配
<?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/>
</beans>
1.@Autowired
@Autowired
是 Spring 框架中的一个非常核心和常用的注解,它用于实现依赖的自动注入。当你在 Spring 管理的 bean 的字段、setter 方法或构造函数上标注 @Autowired
注解时,Spring 容器会自动查找匹配的 bean 并将其注入到被注解的字段、方法参数或构造函数的参数中。
实体类:
public class person {
@Autowired
private friend friend;
@Autowired
private girlFriend girlFriend;
private String name;
public person() {
}
public person(com.lzh.pojo.friend friend, com.lzh.pojo.girlFriend girlFriend, String name) {
this.friend = friend;
this.girlFriend = girlFriend;
this.name = name;
}
public void show(){
System.out.println("my friend is "+this.friend.getName());
System.out.println("my girlfriend is "+this.girlFriend.getName());
}
}
<bean id="friend" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<bean id="girlFriend" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<bean id="person" class="com.lzh.pojo.person"></bean>
2.@Qualifier
@Qualifier
注解在Spring框架中用于在自动装配时提供额外的限定符,以便在存在多个相同类型的bean时,能够精确地指定应该注入哪一个bean。这个注解经常与@Autowired
注解一起使用,以解决byType
自动装配可能产生的歧义。
实体类
public class person {
@Autowired
@Qualifier( value = "friend2")
private friend friend;
@Autowired
@Qualifier( value = "girlFriend2")
private girlFriend girlFriend;
private String name;
public person() {
}
public person(com.lzh.pojo.friend friend, com.lzh.pojo.girlFriend girlFriend, String name) {
this.friend = friend;
this.girlFriend = girlFriend;
this.name = name;
}
public void show(){
System.out.println("my friend is "+this.friend.getName());
System.out.println("my girlfriend is "+this.girlFriend.getName());
}
}
xml文件:
<bean id="friend1" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<bean id="friend2" class="com.lzh.pojo.friend">
<property name="name" value="jcx"></property>
</bean>
<bean id="girlFriend1" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<bean id="girlFriend2" class="com.lzh.pojo.girlFriend">
<property name="name" value="yyy"></property>
</bean>
使用之前的测试方法:
3.@Resource
@Resource
注解可以用于字段、setter 方法或构造函数上,以指定 Spring 容器应该注入哪个 bean。与 @Autowired
类似,它也可以用于自动装配 bean,但它在查找匹配的 bean 时具有不同的行为。@Autowired
默认按类型(byType)装配依赖项,而 @Resource
默认按名称(byName)装配。如果 @Resource
没有显式指定名称,并且按名称装配失败,那么它会回退到按类型装配
在pom.xml导入依赖
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
实体类
public class person {
@Resource
private friend friend;
@Resource
private girlFriend girlFriend;
private String name;
public person() {
}
public person(com.lzh.pojo.friend friend, com.lzh.pojo.girlFriend girlFriend, String name) {
this.friend = friend;
this.girlFriend = girlFriend;
this.name = name;
}
public void show(){
System.out.println("my friend is "+this.friend.getName());
System.out.println("my girlfriend is "+this.girlFriend.getName());
}
}
xml文件:
<bean id="friend" class="com.lzh.pojo.friend">
<property name="name" value="zsy"></property>
</bean>
<!--bean id="friend2" class="com.lzh.pojo.friend">
<property name="name" value="jcx"></property>
</bean-->
<bean id="girlFriend" class="com.lzh.pojo.girlFriend">
<property name="name" value="xxx"></property>
</bean>
<bean id="person" class="com.lzh.pojo.person"></bean>
测试: