获取bean实例的三种方式:
随意创建一个User类进行配置:
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 class="entity.User" id="user"></bean> <bean class="entity.User" id="user1"></bean> </beans>
测试类
package test;
import entity.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IocTest {
@Test
public void fun(){
// 加载spring容器
// ApplicationContext spring顶层的核心接口
// ClassPathXmlApplicationContext 根据项目路径的xml文件来实例化spring容器
// FileSystemXmlApplicationContext 根据磁盘路径的xml文件来实例化spring容器
// AnnotationConfigApplicationContext 根据javaconfig 来配置实例化spring容器
// 容器实例化的时候就会加载所有的bean
// 在容器实例化的时候就会将bean实例化
ApplicationContext app = new ClassPathXmlApplicationContext("spring_ioc.xml");
// 获取实例的三种方式
// 1、通过class类型获取
// User user = app.getBean(User.class);
///2、通过id+强制转换获取
// User user = (User) app.getBean("user");
// 当xml配置文件中配置的bean是同一个类不同id,那么就使用id加class的方式获取实例化
///3、id+类型 的方式获取不同id相同类的实例
User user = app.getBean("user",User.class);
User user1 = app.getBean("user1",User.class);
System.out.println(user.toString());
System.out.println("user1 - " + user1.toString());
}
}

三种方式中,使用id+类型的方式最稳妥;
spring的xml配置文件中<beans>标签中的子标签:
<?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 class="entity.User" id="user"> <description>对bean的描述信息</description> </bean> <bean class="entity.User" id="user1"></bean> <alias name="user" alias="username"/> <!--起别名--> <import resource="spring_ioc.xml"/> <!--导入--> </beans>
bean :
JavaBean的依赖注入
alias :
给对应的name起别名
description:
描述信息
import :
导入标签,可以在一个xml中导入另外的xml文件
User userAlias = app.getBean("username",User.class);
System.out.println("别名 - "+userAlias.toString());
通过别名获取实例:

@Before注解
@Before方法会在@Test方法之前执行:
package test;
import entity.User;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IocTest {
ApplicationContext app;
@Before
public void before(){
// 加载spring容器
// ApplicationContext spring顶层的核心接口
// ClassPathXmlApplicationContext 根据项目路径的xml文件来实例化spring容器
// FileSystemXmlApplicationContext 根据磁盘路径的xml文件来实例化spring容器
// AnnotationConfigApplicationContext 根据javaconfig 来配置实例化spring容器
// 容器实例化的时候就会加载所有的bean
// 在容器实例化的时候就会将bean实例化
app = new ClassPathXmlApplicationContext("spring_ioc.xml");
}
@Test
public void fun(){
// 获取实例的三种方式
// 1、通过class类型获取
// User user = app.getBean(User.class);
///2、通过id+强制转换获取
// User user = (User) app.getBean("user");
// 当xml配置文件中配置的bean是同一个类不同id,那么就使用id加class的方式获取实例化
///3、id+类型 的方式获取不同id相同类的实例
User user = app.getBean("user",User.class);
User user1 = app.getBean("user1",User.class);
System.out.println(user.toString());
System.out.println("user1 - " + user1.toString());
User userAlias = app.getBean("username",User.class);
System.out.println("别名 - "+userAlias.toString());
}
}
运行:

可以发现,这样就减少了代码的重复度;
除了alias标签可以起别名外,bean标签中的name属性也可以(并且可以使用 空格 逗号 分号 进行分隔):
<bean class="entity.User" id="user" name="user1 user2,user3;user4"> <description>对bean的描述信息</description> </bean>
给id=user的bean起别名为user1,user2,user3,后面还能增加。。。。
并且可以使ioc容器通过别名获取实例。
依赖注入(使用xml配置set方法设置bean中的值)
<!--基于set方法的依赖注入--> <bean class="entity.User" id="userA"> <property name="id" value="1"></property> <property name="userName" value="假名"></property> <property name="realName" value="真名"></property> </bean>
@Test
public void fun1(){
User userA = app.getBean("userA",User.class);
System.out.println(userA.toString());
}
结果:
<property name="id" 的name中的值查找的是对应的set方法:
例如 setXxx()方法,配置时name的值就应该是xxx,
基于构造函数:
首先得要有带参的构造函数:
name可以省略,只有value属性:
<!--基于构造函数的依赖注入--> <bean class="entity.User" id="userB"> <constructor-arg name="id" value="1"></constructor-arg> <constructor-arg name="userName" value="假名"></constructor-arg> <constructor-arg name="realName" value="真名"></constructor-arg> </bean>
@Test
public void fun2(){
User userA = app.getBean("userB",User.class);
System.out.println("userB - "+userA.toString());
}
只有value属性:
省略name可能会导致相同类型属性的赋值顺序改变。
此外还能使用index指定顺序:
index是根据构造函数中参数的顺序来指定;
可以使用type指定属性的类型:
使用name就不需要其它设置项了;
复杂类的依赖注入和联系:
创建一个Person类和Wife类:
package entity; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; public class Person { private Integer id; private String name; private String gender; private Date birth; private List<String> ls; private Map<Integer,String> course; private Wife wife; @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", birth=" + birth + ", ls=" + ls + ", course=" + course + ", wife=" + wife + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return Objects.equals(id, person.id) && Objects.equals(name, person.name) && Objects.equals(gender, person.gender) && Objects.equals(birth, person.birth) && Objects.equals(ls, person.ls) && Objects.equals(course, person.course) && Objects.equals(wife, person.wife); } @Override public int hashCode() { return Objects.hash(id, name, gender, birth, ls, course, wife); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public List<String> getLs() { return ls; } public void setLs(List<String> ls) { this.ls = ls; } public Map<Integer, String> getCourse() { return course; } public void setCourse(Map<Integer, String> course) { this.course = course; } public Wife getWife() { return wife; } public void setWife(Wife wife) { this.wife = wife; } }
package entity; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; public class Wife { private Integer id; private String name; private String gender; private Date birth; private List<String> ls; private Map<Integer,String> course; @Override public String toString() { return "Wife{" + "id=" + id + ", name='" + name + '\'' + ", gender='" + gender + '\'' + ", birth=" + birth + ", ls=" + ls + ", course=" + course + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Wife wife = (Wife) o; return Objects.equals(id, wife.id) && Objects.equals(name, wife.name) && Objects.equals(gender, wife.gender) && Objects.equals(birth, wife.birth) && Objects.equals(ls, wife.ls) && Objects.equals(course, wife.course); } @Override public int hashCode() { return Objects.hash(id, name, gender, birth, ls, course); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public List<String> getLs() { return ls; } public void setLs(List<String> ls) { this.ls = ls; } public Map<Integer, String> getCourse() { return course; } public void setCourse(Map<Integer, String> course) { this.course = course; } }
配置文件:
<!-- 复杂类的依赖注入 --> <bean class="entity.Person" id="person"> <property name="id" value="1"/> <property name="gender" value="nan"></property> <property name="name" value="zs"></property> <property name="wife" ref="wife"></property><!--ref引用外面配置的wife--> </bean> <bean class="entity.Wife" id="wife"></bean>
@Test public void fun3(){ Person person = app.getBean("person", Person.class); System.out.println("person - "+person.toString()); }
结果:
1 | person - Person{id=1, name= 'zs' , gender= 'nan' , birth= null , ls= null , course= null , wife=Wife{id= null , name= 'null' , gender= 'null' , birth= null , ls= null , course= null }} |
除了外部引用,还可以进行内部配置:
输出结果:
1 | person - Person{id=1, name= 'zs' , gender= 'nan' , birth= null , ls= null , course= null , wife=Wife{id=<strong>1</strong>, name= '<strong>老王</strong>' , gender= 'null' , birth= null , ls= null , course= null }} |
效果都是一样的;
但是外部的bean可以给其它bean复用,内部就只能自己使用。
然后是List类型的配置:
结果:
Map类型的配置:
结果:
p命名空间简化set方法属性设置
不支持集合、Map等复杂数据结构,可以与前面的方式结合使用
第一次在xml的bean输入p:会报错,因为没有导入命名空间,使用idea可以按住alt+enter导入
<!--p命名空间简化基于set方法注入属性值--> <bean class="entity.Wife" id="wife" p:name="p命名空间" p:gender="f"></bean>
@Test
public void fun4(){
Wife wife = app.getBean("wife", Wife.class);
System.out.println("p命名空间 - "+wife.toString());
}
C命名空间基于构造方法设置属性值:
同样不支持集合、Map等复杂数据结构,可以与前面的方式结合使用
Spring默认加载无参构造,使用C命名空间时需要创建有参构造,在创建有参构造的同时一定要创建无参构造,否则有参构造会覆盖无参构造,没有无参构造会报错
<!--c命名空间简化基于构造方法注入属性值--> <bean class="entity.User" id="cUser" c:id="1" c:userName="C命名空间" c:realName="C命名空间real"></bean>
@Test public void fun5(){ User userC = app.getBean("cUser", User.class); System.out.println("C命名空间 - "+userC.toString()); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)