前言
Spring中IOC容器的实现方式——依赖注入(DI)在前一篇博文中已讲述过,但是那篇是显式的在beans.xml
文件中定义的。
本文用于讲述Spring中IOC容器依赖注入(DI)的第二种方式,即:自动装配bean。
环境搭建
pom.xml
注:
- 需要引入
spring-context
依赖。
spring-context的dependency引入:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
完整的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Spring-DI-Autowired</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.13</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>15</maven.compiler.source>
<maven.compiler.target>15</maven.compiler.target>
</properties>
</project>
pojo
Dog.java
package com.langjialing;
public class Dog {
public void shout(){
System.out.println("汪……");
}
}
Cat.java
package com.langjialing;
public class Cat {
public void shout(){
System.out.println("喵……");
}
}
Person.java
package com.langjialing;
public class Person {
private Cat cat;
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.langjialing.Cat" />
<bean id="dog" class="com.langjialing.Dog" />
<bean id="person" class="com.langjialing.Person">
<property name="name" value="langjialing"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
</beans>
Test测试类
import com.langjialing.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
person.getDog().shout();
person.getCat().shout();
}
}
目录结构
自动装配实现一:基于beans.xml上下文实现
注:
- 只需修改
beans.xml
文件即可。 - autowire="byName":会自动在容器上下文中查找和自己对象set方法后面的值对应的bean的id。
- autowire="byType":会自动在容器上下文中查找和自己对象class相同的bean。
修改beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.langjialing.Cat" />
<bean id="dog" class="com.langjialing.Dog" />
<!-- <bean id="person" class="com.langjialing.Person">-->
<!-- <property name="name" value="langjialing"/>-->
<!-- <property name="cat" ref="cat"/>-->
<!-- <property name="dog" ref="dog"/>-->
<!-- </bean>-->
<!--
autowire="byName":会自动在容器上下文中查找和自己对象set方法后面的值对应的bean的id。
autowire="byType":会自动在容器上下文中查找和自己对象class相同的bean。
-->
<bean id="person" class="com.langjialing.Person" autowire="byName">
<property name="name" value="langjialing"/>
</bean>
</beans>
修改beans.xml后进行测试
注:
- 测试类无需变动。
自动装配实现二:注解实现自动装配(官方推荐)
注:
- 注解实现自动装配的方式为Spring官方推荐的方式。
- 此种方式比beans.xml的方式更简洁。
@Autowired注解对应的beans.xml文件
官方简介:需导入context约束,并配置注解的支持
注:
- 此内容来自Spring官方;
- 注解支持的关键代码:
<context:annotation-config/>
,否则即会报错。
<?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>
项目实际的beans.xml文件实现
<?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="cat" class="com.langjialing.Cat"/>
<bean id="dog" class="com.langjialing.Dog"/>
<bean id="person" class="com.langjialing.Person"/>
</beans>
@Autowire注解实现自动装配(修改Person.java)
注:
- @Autowired注解的属性,setter方法可省略,getter方法不可省略。
package com.langjialing;
import org.springframework.beans.factory.annotation.Autowired;
public class Person {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
}
Test测试类
注:
- Test测试类使用上文的即可。
import com.langjialing.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
person.getDog().shout();
person.getCat().shout();
}
}
多个相同Bean时应当如何使用@Autowired注解呢?
在本例中,如果IOC容器中有多个相同类型bean时,直接使用@Autowired注解会报错。那么应当如何注入呢?
例如:
解决:@Qualifier("dog1")
使用@Qualifier("dog1")
注解进行区分。
自动装配实现三:Java原生注解@Resource实现
注:
- 使用方式与 @Autowired 注解基本一致。
- @Resource注解先匹配beans.xml中的id值,匹配不到id值时继而匹配class值。两者都无法匹配到时报错。
- 此注解相对于@Autowired注解使用较少,一般情况下使用@Autowired注解。
pom.xml中导入依赖
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
<scope>compile</scope>
</dependency>
注解使用
注:
- 在Person.java中引入
import javax.annotation.Resource;