Spring Bean详解


Spring Bean作用域

默认情况下,所有的 Spring Bean 都是单例的,也就是说在整个 Spring 应用中, Bean 的实例只有一个

如果我们需要创建多个实例的对象,那么应该将 Bean 的 scope 属性定义为 prototype,如果 Spring 需要每次都返回一个相同的 Bean 实例,则应将 Bean 的 scope 属性定义为 singleton。(默认)

Spring 5 共提供了 6 种 scope 作用域

这里只说 单例 和 多例的配置

多例

xml 复制代码
<!-- User -->
<bean class="com.liu.c.User" id="user" scope="prototype">
    <constructor-arg name="age" value="15"/>
    <constructor-arg name="name" value="小张"/>
</bean>
java 复制代码
public class TestUser {
    public static void main(String[] args) {
        String springProperties = "spring.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(springProperties);
        User user = context.getBean("user", User.class);
        User user1 = context.getBean("user", User.class);
        System.out.println(user.hashCode());
        System.out.println(user1.hashCode());
    }
}

显然是不同的对象

复制代码
1554358
17185802

单例

xml 复制代码
<bean class="com.liu.c.User" id="user" scope="singleton">
    <constructor-arg name="age" value="15"/>
    <constructor-arg name="name" value="小张"/>
</bean>

hash值相同,同一个对象,单例模式

复制代码
17139697
17139697

OK


Spring Bean的声明周期

在传统的 Java 应用中,Bean 的生命周期很简单,使用 Java 关键字 new 进行 Bean 的实例化后,这个 Bean 就可以使用了。一旦这个 Bean 长期不被使用,Java 自动进行垃圾回收。

Spring 中 Bean 的生命周期较复杂,大致可以分为以下 5 个阶段:

Bean 的实例化

Bean 属性赋值

Bean 的初始化

Bean 的使用

Bean 的销毁

Spring 根据 Bean 的作用域来选择 Bean 的管理方式,

对于 singleton 作用域的 Bean 来说,Spring IoC 容器能够精确地控制 Bean 何时被创建、何时初始化完成以及何时被销毁;

对于 prototype 作用域的 Bean 来说,Spring IoC 容器只负责创建,然后就将 Bean 的实例交给客户端代码管理,Spring IoC 容器将不再跟踪其生命周期。

我们可以在 Spring Bean 的 Java 类中,通过实现 InitializingBean 和 DisposableBean 接口,指定 Bean 的生命周期回调方法。

我们还可以在 Spring 的 XML 配置中,通过 元素中的 init-method 和 destory-method 属性,指定 Bean 的生命周期回调方法。

我们还可以通过 JSR-250 的 @PostConstruct 和 @PreDestroy 注解,指定 Bean 的生命周期回调方法。

Spring Bean继承

在 Spring XML 配置中,我们通过子 Bean 的 parent 属性来指定需要继承的父 Bean,配置格式如下

xml 复制代码
<!--父Bean-->
<bean id="parentBean" class="xxx.xxxx.xxx.ParentBean" >
    <property name="xxx" value="xxx"></property>
    <property name="xxx" value="xxx"></property>
</bean> 
<!--子Bean--> 
<bean id="childBean" class="xxx.xxx.xxx.ChildBean" parent="parentBean"></bean>

Bean定义模板

在父 Bean 的定义中,有一个十分重要的属性,那就是 abstract 属性。如果一个父 Bean 的 abstract 属性值为 true,则表明这个 Bean 是抽象的。

抽象的父 Bean 只能作为模板被子 Bean 继承,它不能实例化,也不能被其他 Bean 引用,更不能在代码中根据 id 调用 getBean() 方法获取,否则就会返回错误。

在父 Bean 的定义中,既可以指定 class 属性,也可以不指定 class 属性。如果父 Bean 定义没有明确地指定 class 属性,那么这个父 Bean 的 abstract 属性就必须为 true。

相关推荐
一个有温度的技术博主2 分钟前
两级缓存一致性实战:Redis + 本地缓存,如何不让数据“分裂”?
redis·spring·缓存
步行cgn2 分钟前
Spring AOP 实战:安全日志
python·安全·spring
做个文艺程序员4 分钟前
MQ第04篇:ActiveMQ深度解析:JMS规范、Spring JMS整合与企业级异步通信实战
spring·消息队列·activemq·java-activemq·jms
10mAh16 分钟前
【Java】ArrayList 遍历删除为什么报错?三种写法与漏删复现
java·开发语言·windows
JavaGuide29 分钟前
DeepSeek Harness 重磅更新,Codex、Claude Code 子智能体进官方插件列表了,还有 Git 工作树和思考翻译!
前端·后端
thefool11226632 分钟前
多线程 4
java
Rain的Java大神之路1 小时前
[特殊字符]8年Java老兵转型AI Agent:90%的人挂在同一个坑,根本不用学Python!(万字实战复盘,建议收藏)
java·数据库·人工智能·后端·python·spring·ai编程
高频因子挖掘机1 小时前
A股分钟K线数据占内存:先缩小请求范围,还是换 DataFrame 工具?
后端·github·api
高级程序源1 小时前
springboot大学生体测系统72170-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·django·课程设计
IT研究室1 小时前
最新计算机毕业设计选题推荐-基于spring boot的文学名著分享系统-网站-文档指导-Java-springboot
java·spring boot·课程设计