SpringBean的生命周期

Spring Bean 是什么

Bean 定义本质上是创建一个或多个对象的配方。容器在请求时查看有名称的Bean的配方,并使用该Bean定义所封装的配置元数据来创建(或获取)一个实际对象。

在 Spring 框架中,Bean 是指被 Spring 容器管理或者实例化的对象。Bean 可以是任何一个由 Java 实例,例如数据库连接、业务逻辑类、控制器等等。Spring Bean 实例的创建和管理是由 Spring 容器负责的,而不是应用程序本身。

Bean 给我们带来的优势主要是将对象的创建和管理和业务逻辑分离开,主打一个低耦合,让程序本身更易于维护和管理,比如在我们的项目中,连接数据库的创建和管理只需要交给 Spring 容器就行,业务逻辑在 Service层完成,当需要连接另一个数据库,只需要修改 Spring 的配置文件即可。

Bean 的作用范围

为什么Bean默认为单例?

  • 为了提高性能

适合交给容器进行管理的bean

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合交给容器进行管理的bean

  • 封装实体的域对象

实例化 Bean 的方式

构造方法

提供可使用的构造方法

public class BookServiceImpl implements BookService {
    public BookServiceImpl() {
        System.out.println(" book constructor...");
    }

    @Override
    public void schedule() {
        System.out.println("预定了一本书...");
    }
}

如果代码中只有无参构造的话,比如上面代码,那么里面的无参构造可以省略,Spring 会使用默认的无参构造,但是如果有带参构造的话,那就要显式写出无参构造

xml配置

<bean id="bookService" class="com.springbean.service.impl.BookServiceImpl"/>

如果不提供无参构造方法的话,就会抛出异常:

Caused by: java.lang.NoSuchMethodException: com.springbean.service.impl.BookServiceImpl.<init>()

实例工厂

使用FactoryBean实例化 bean

xml 配置

需要先配置一个工厂 bean

<bean id="bookFactory" class="com.springbean.appFroInstance.BookFacBean"/>

FactoryBean 实例

public class BookFac implements FactoryBean<BookService> {

    @Override
    public BookService getObject() throws Exception {
        return new BookServiceImpl();
    }

    @Override
    public Class<?> getObjectType() {
        return BookService.class;
    }

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

静态工厂

xml 配置

<bean id="bookFactory" class="com.springbean.factory.StaticBookFactory" factory-method="getBookSchedule"/>

静态方法

public class StaticBookFactory {
    public static BookService getBookSchedule(){
        return new BookServiceImpl();
    }
}

Bean 的生命周期

演示链接

概念

bean 的生命周期

简单来说就是,bean从创建到销毁的整体过程

bean 的生命周期控制

bean创建后到销毁前做一些事情

生命周期过程

简要版

初始化容器

  1. 创建对象(内存分配)
  2. 执行构造方法
  3. 执行属性注入(set)
  4. 执行bean初始化方法

使用bean

  1. 执行业务操作

关闭 / 销毁容器

  1. 执行bean销毁方法

img

详细版

  • 实例化:Spring 容器根据配置文件或注解实例化对象
  • 属性注入:Spring 将依赖(通过 setter 或者字段注入)注入到 Bean 实例中
  • 初始化前的扩展机制:如果 Bean 实现了BeanNameAware等 aware 接口,则执行 aware 注入
  • 初始化前(BeanPostProcessor):在 Bean 初始化前,可以通过 BeanPostProcessor 接口对 Bean 进行一些额外的处理
  • 初始化:调用InitializingBean接口的afterPropertiesSet()方法或通过init-method属性指定的方法
  • 初始化后(BeanPostProcessor):在 Bean 初始化后,可以通过BeanPostProcessor进行进一步处理
  • 使用Bean:Bean 已经初始化完成,可以被容器中的其他 Bean 使用
  • 销毁:当容器关闭时,Spring 调用 DisposableBean 接口的destroy()或者通过destroy-method属性指定的销毁方法。

img

代码模拟

没添加set方法(属性注入)

1)xml 配置

<bean id="bookDao" class="com.springbean.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"/>

2)业务逻辑代码

编写接口代码:

public interface BookDao {
    void save();

    void init();

    void destroy();
}

实现类:

public class BookDaoImpl implements BookDao {
    @Override
    public void save() {
        System.out.println("book dao save...");
    }

    @Override
    public void init() {
        System.out.println("init...");
    }

    @Override
    public void destroy() {
        System.out.println("destroy...");
    }
}

3)测试代码:

public class BookMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        applicationContext.registerShutdownHook();
        BookDao bookDao = (BookDao) applicationContext.getBean("bookDao");

        bookDao.save();

//        applicationContext.close();
    }
}

registerShutdownHookSpring框架中ConfigurableApplicationContext接口的一个方法,用于注册一个JVM关闭钩子

作用:在JVM关闭的时候,确保Spring容器可以优雅关闭,并执行所有单例bean的销毁回调方法

工作原理

  1. 注册钩子:向 JVM 注册一个关闭钩子线程
  2. JVM 关闭时触发:当 JVM 收到关闭信号(如 Ctrl+C、系统关闭等)时,会调用这个钩子
  3. 关闭 Spring 容器:钩子线程会调用 ApplicationContextclose() 方法
  4. 执行销毁回调:Spring 会调用所有单例 bean 的销毁方法(如 @PreDestroyDisposableBean 接口、destroy-method 等)

在虚拟机退出前先关闭容器再退出虚拟机

4)执行结果:

init...
book dao save...
destroy...

添加set

在业务逻辑中添加set方法的bean初始化容器的顺序变化

1)先看执行结果的变化

# 创建对象
init...  
# 执行构造方法
service constructor...
# 执行属性注入
service set ...
# 执行 bean 初始化方法
service init...
# 执行业务操作
预定了一本书...
book dao save...
# 关闭销毁容器
service destroy...
destroy...

2)添加set之后的xml配置

<bean id="bookService" class="com.springbean.service.impl.BookServiceImpl">
  <property name="bookDao" ref="bookDao"/>
</bean>

3)业务逻辑代码

实现InitializingBean, DisposableBean接口

public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {

    private BookDao bookDao;
    
    public BookServiceImpl() {
        System.out.println("service constructor...");
    }

    @Override
    public void schedule() {
        System.out.println("预定了一本书...");
        bookDao.save();
    }

    public void setBookDao(BookDao bookDao) {
        System.out.println("service set ...");
        this.bookDao = bookDao;
    }

    public void destroy() throws Exception{
        System.out.println("service destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("service init...");
    }
}

afterPropertiesSet:初始化回调

源码解释:

由包含的BeanFactory在设置所有bean属性并满足BeanFactoryAwareApplicationContextAware等条件后调用。该方法允许bean实例在已设置所有bean属性时对其整体配置和最终初始化进行验证。

抛出异常: 在出现配置错误(例如未能设置一个必要属性)或由于其他任何原因初始化失败的情况下

4)测试函数代码:

public class BookMain {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        applicationContext.registerShutdownHook();

        BookDao bookDao = (BookDao) applicationContext.getBean("bookDao");
        BookService bookService = (BookService) applicationContext.getBean("bookService");
        bookService.schedule();

    }
}
posted @ 2025-11-02 18:52  Lantz12  阅读(6)  评论(0)    收藏  举报