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创建后到销毁前做一些事情
生命周期过程
简要版
初始化容器
- 创建对象(内存分配)
- 执行构造方法
- 执行属性注入(set)
- 执行
bean初始化方法
使用bean
- 执行业务操作
关闭 / 销毁容器
- 执行
bean销毁方法

详细版
- 实例化: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属性指定的销毁方法。

代码模拟
没添加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();
}
}
registerShutdownHook是Spring框架中ConfigurableApplicationContext接口的一个方法,用于注册一个JVM关闭钩子
作用:在JVM关闭的时候,确保Spring容器可以优雅关闭,并执行所有单例bean的销毁回调方法
工作原理
- 注册钩子:向 JVM 注册一个关闭钩子线程
- JVM 关闭时触发:当 JVM 收到关闭信号(如 Ctrl+C、系统关闭等)时,会调用这个钩子
- 关闭 Spring 容器:钩子线程会调用
ApplicationContext的close()方法 - 执行销毁回调:Spring 会调用所有单例 bean 的销毁方法(如
@PreDestroy、DisposableBean接口、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属性并满足BeanFactoryAware、ApplicationContextAware等条件后调用。该方法允许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();
}
}