Spring笔记:bean的自动装配
装配就是指为对象的属性赋值,除了在xml文件中使用property标签显式赋值,还有其他的方式进行属性的自动赋值(装配)。
1. 使用bean标签的autowire属性自动装配。
bean标签的autowire属性常用的值有byName和byType,也代表了两种不同的自动装配方式。autowire为byName时,会根据对象的属性名去查找有没有相同名称的bean,因此这种方式需要保证xml中对应的bean是唯一的。byType会根据属性的类型去查找对应的bean,这种方式必须保证xml中该类型的对象只有一个,而且就算对应的bean标签没有设置id值,也能找到进行装配。以下是使用byName进行自动装配的示例:
Cat类:
package com.yun.pojo;
public class Cat {
public void shout(){
System.out.println("I'm a Cat!");
}
}
Dog类:
package com.yun.pojo;
public class Dog {
public void shout(){
System.out.println("I'm a Dog!");
}
}
Person类:
package com.yun.pojo;
public class Person {
private String name;
private Dog dog;
private Cat cat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", dog=" + dog +
", cat=" + cat +
'}';
}
}
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 http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat" class="com.yun.pojo.Cat"/>
<bean id="dog" class="com.yun.pojo.Dog"/>
<!-- 配置了autowire="byName"之后,Spring会根据属性名自动寻找id名称相同的bean进行关联 -->
<bean id="person" class="com.yun.pojo.Person" autowire="byName">
<property name="name" value="zhangsan"/>
<!-- 以下是使用property标签进行赋值的方式,使用了autowire自动装配之后,就不需要配置对应的property标签了 -->
<!-- <property name="cat" ref="cat"/>-->
<!-- <property name="dog" ref="dog"/>-->
</bean>
</beans>
测试:
import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
person.getCat().shout();
person.getDog().shout();
}
}
2. 使用注解进行自动装配
我先把示例中会用到的基础的类列出来。
Cat类:
package com.yun.pojo;
public class Cat {
public void shout(){
System.out.println("I'm a Cat!");
}
}
Dog类:
package com.yun.pojo;
public class Dog {
public void shout(){
System.out.println("I'm a Dog!");
}
}
测试类:
import com.yun.pojo.Person;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person = context.getBean("person", Person.class);
person.getCat().shout();
person.getDog().shout();
}
}
2.1 @Autowired
这个注解可以添加到类属性上,通常来讲,被注解的属性是另一个bean,那么属性名和bean的id值应该是一致的,这种方式其实就是byName和byType的结合。另外, @Autowired
注解可以传入参数, @Autowired(required = false)
表示这个属性可以为null。使用这个注解需要在xml中添加的扩展有:
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
<context:annotation-config/>
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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 这个扩展以及上面的三个扩展千万别忘了,不然注解没法生效 -->
<context:annotation-config/>
<bean id="cat" class="com.yun.pojo.Cat"/>
<bean id="dog" class="com.yun.pojo.Dog"/>
<bean id="person" class="com.yun.pojo.Person"/>
</beans>
Person类:
package com.yun.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
public class Person {
private String name;
@Autowired // 注解的属性名需要和bean的id保持一致
private Dog dog;
@Autowired // @Autowired(required = false),表示这个属性可以为null。
private Cat cat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", dog=" + dog +
", cat=" + cat +
'}';
}
}
2.2 @Nullable
表示被注解的属性可以为null。
package com.yun.pojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
public class Person {
private String name;
@Autowired
private Dog dog;
@Autowired
private Cat cat;
public Person() {
}
// @Nullable表示传入参数时这个属性可以为null
public Person(@Nullable String name) {
this.name = name;
}
}
2.3 @Qualifier
当同一个class在一个xml中配置了多个bean,可以使用 @Qualifier
注解来指定一个具体的bean。
public class Person {
private String name;
@Autowired
@Qualifier(value = "dog2") // @Qualifier用来指定一个具体的bean
private Dog dog;
@Autowired
private Cat cat;
}
2.3 其他常用注解
想要使用以下的注解,需要在xml中添加 <context:component-scan base-package="com.yun.pojo"/>
。
<?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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 指定需要扫面Spring注解的包 -->
<context:component-scan base-package="com.yun"/>
<context:annotation-config/>
</beans>
@Component/@Controller/@Service/@Repository
这几个注解需要加在bean类上,加上后就相当于在xml中配置了对应的bean了,表示这个类被Spring管理了。这几个注解的功能都是相同的,只是用在不同的场景, @Component
用在pojo包中, @Controller/@Service/@Repository
则分别用在MVC三层架构的controller、service和dao中。
Java类:
package com.yun.pojo;
import org.springframework.stereotype.Component;
// @Component注解相当于xml中的<bean id="user" class="com.yun.pojo.User"/>
// 自动生成的bean对象名称就是类名的首字母小写形式
@Component
public class User {
private String name = "zhangsan";
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
@Value
配置属性值。
package com.yun.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
// @Value相当于xml配置中的<property name="name" value="zhangsan"/>
// 如果属性有对应的set方法,那么此注解也可以运用到set方法上
@Value("zhangsan")
private String name;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
@Scope
相当于xml中bean标签的scope属性,可以通过参数进行赋值。
package com.yun.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("singleton")
public class User {
@Value("zhangsan")
private String name;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
2.4 xml配置类
Spring的配置信息,除了xml配置外,还可以使用Spring配置类来进行配置,配置类的效果等价于xml配置,有了Spring配置类后,就用不到xml配置了。使用示例如下:
普通Java类:使用方式和xml配置的方式是一样的。
package com.yun.pojo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class User {
@Value("zhangsan")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
Spring配置类:xml配置的功能,配置类中都有,只不过是通过注解来实现的。
package com.yun.config;
import com.yun.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
// @Configuration注解的配置类也会被Spring管理,因为它本身也是被@Component注解的
// 配置类的作用和Spring的xml配置文件是一样的,或者说这个类就是用来替代xml配置文件的。
@Configuration
// 被@ComponentScan注解之后,也可以指定扫描的目录,相当于xml配置中的<context:component-scan base-package="com.yun"/>
@ComponentScan("com.yun.pojo")
// 导入其他的Spring配置类,相当于xml配置中的<import resource="beans2.xml"/>
@Import(BeanConfig2.class)
public class BeanConfig {
// @Bean在get方法上使用,相当于xml配置中的<bean id="getUser" class="com.yun.pojo.User"/>
// 注意bean标签的id属性值是方法名称
@Bean
public User getUser(){
return new User();
}
}
测试:
import com.yun.config.BeanConfig;
import com.yun.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyTest {
public static void main(String[] args) {
// 使用了Spring配置类的方式,就需要使用AnnotationConfigApplicationContext了,不再是ClassPathXmlApplicationContext了
ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig .class);
// 根据方法名获取对象
User user = context.getBean("getUser", User.class);
System.out.println(user);
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2019-12-03 设计模式:命令模式(Python)