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。

相关推荐
北执南念7 分钟前
项目代码生成工具
java
中国lanwp13 分钟前
springboot logback 默认加载配置文件顺序
java·spring boot·logback
苹果酱05671 小时前
【Azure Redis 缓存】在Azure Redis中,如何限制只允许Azure App Service访问?
java·vue.js·spring boot·mysql·课程设计
Java致死1 小时前
单例设计模式
java·单例模式·设计模式
胡子发芽1 小时前
请详细解释Java中的线程池(ThreadPoolExecutor)的工作原理,并说明如何自定义线程池的拒绝策略
java
沫夕残雪1 小时前
Tomcat的安装与配置
java·tomcat
Rabbb1 小时前
C# JSON属性排序、比较 Newtonsoft.Json
后端
蓝易云1 小时前
在Linux、CentOS7中设置shell脚本开机自启动服务
前端·后端·centos
胡子发芽1 小时前
请解释Java中的NIO(New I/O)与传统I/O的区别,并说明NIO中的关键组件及其作用
java
小布不吃竹2 小时前
SpringMVC框架
spring·mvc