一、注册 Bean
基于 XML 配置的方式,可以在 Spring 的配置文件中使用 bean 标签来配置 bean 的信息。
Person 类的声明:
1 public class Person {
2 private String lastName;
3 private Integer age;
4 private String gender;
5 private String email;
6 //构造器与 setter & getter
7 }
使用 bean 标签在配置文件中注册:
<!--注册一个Person对象,Spring会自动创建这个Person对象-->
<!--
一个bean标签可以注册一个组件(对象,类)
class:写要注册的组件全类名
id:这个对象的唯一标识
-->
<bean id="person01" class="com.njf.spring.bean.Person">
<!--
使用property标签为Person对象的属性赋值
name="lastName": 指定属性名
value="子龙": 指定属性值
-->
<property name="lastName" value="子龙"></property>
<property name="age" value="18"></property>
<property name="email" value="zilong@achang.com"></property>
<property name="gender" value="男"></property>
</bean>
二、获取 Bean
我们知道可以通过ApplicationContext的getBean方法来获取Spring容器中已初始化的bean。getBean一共有以下四种方法原型:
一共有以下四种方法原型:
getBean(String name)
getBean(Class<T> type)
getBean(String name,Class<T> type)
getBean(String name,Object[] args)
(1)方式一
1 | public Object getBean(String name) throws BeansException |
这个方法应该是通过bean的名称来得到bean的对象,实现了接口beanfactory,返回一个独立或者被共享的bean实例。
测试:
注册:在 ioc.xml 的配置文件中注册一个 bean
<bean id="person01" class="com.njf.spring.bean.Person">
<property name="lastName" value="子龙"></property>
<property name="age" value="18"></property>
<property name="email" value="zilong@achang.com"></property>
<property name="gender" value="男"></property>
</bean>
获取:
参数 name 表示IOC容器中已经实例化的bean的id或者name,且无论是 id 还是name都要求在IOC容器中是唯一的不能重名。那么这种方法就是通过id或name去查找获取bean.获取bean的参考代码如下:
@Test
public void testGetBean1() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
Person person01 = (Person) ioc.getBean("person01");
System.out.println("person01 = " + person01);
}
(2)方式二
1 | public <T> T getBean(Class<T> requiredType) throws BeansException |
这个方法通过想要获取的bean匹配的类型来获取bean,类型可以是一个接口或者是父类,不可以为空,返回一个匹配到的bean实例。
参数Class<T> type表示要加载的Bean的类型。如果该类型没有继承任何父类(Object类除外)和实现接口的话,那么要求该类型的bean在IOC容器中也必须是唯一的。比如applicationContext.xml配置两个类型完全一致的bean,且都没有配置id和name属性。
测试代码:
/**
* 如果 IOC 容器中这个类型的 bean 有多个,查找就会报错,没有唯一的Bean被定义【NoUniqueBeanDefinitionException】
* org.springframework.beans.factory.NoUniqueBeanDefinitionException:
* No qualifying bean of type [com.njf.spring.bean.Person] is defined
* expected single matching bean but found 3: person01,person02,person04
*
*/
@Test
public void testGetBean2() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
Person person = ioc.getBean(Person.class);
System.out.println("person = " + person);
}
但是由于属于 Person 的bean在IOC容器中不唯一,所以这里会抛出NoUniqueBeanDefinitionException异常。
由此我们可以总结 getBean(String name) 和 getBean(Class<T> type)的异同点。
相同点:都要求id或者name或者类型在容器中的唯一性。
不同点:getBean(String name)获得的对象需要类型转换而getBean(Class<T> type)获得的对象无需类型转换。
(3)方式三
1 | public <T> T getBean(String name, Class<T> requiredType) throws BeansException |
这个方法通过bean的名称和想要获取的bean匹配的类型来获取bean,类型可以是一个接口或者是父类,可以为空(即匹配任意类型),同样返回一个独立或者被共享的bean实例。
这种方式比较适合当类型不唯一时,再通过id或者name来获取bean。
测试代码:
/**
* 通过id与类型在 IOC 容器中查找
*/
@Test
public void testGetBean3() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
Person person02 = ioc.getBean("person02", Person.class);
System.out.println("person02 = " + person02);
}
(4)方式四
1 | public Object getBean(String name, Object... args) throws BeansException |
这个方法通过bean的名称和一些bean的参数来获取bean,(only applied when creating a new instance as opposed to retrieving an existing one)好像是说只能在bean初始化的时候用。
这种方式本质还是通过bean的id或者name来获取bean,通过第二个参数Object[] args可以给bean的属性赋值,赋值的方式有两种:构造方法和工厂方法。但是通过这种方式获取的bean必须把scope属性设置为prototype,也就是非单例模式。
在配置文件中的配置信息:
<bean id="person04" class="com.njf.spring.bean.Person" scope="prototype">
</bean>
测试代码:
@Test
public void testGetBean4() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml");
Person person04 = (Person) ioc.getBean("person04", new Object[]{"王五", 35, "男", "wangwu@126.com"});
System.out.println("person04 = " + person04);
}
如果想通过工厂注入属性,在applicationContext.xml配置如下工厂信息。(后面进行学习)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战