
Bean 定义本质上是创建一个或多个对象的配方。容器在请求时查看有名称的Bean的配方,并使用该Bean定义所封装的配置元数据来创建(或获取)一个实际对象。
在 Spring 框架中,Bean 是指被 Spring 容器管理或者实例化的对象。Bean 可以是任何一个由 Java 实例,例如数据库连接、业务逻辑类、控制器等等。Spring Bean 实例的创建和管理是由 Spring 容器负责的,而不是应用程序本身。
Bean 给我们带来的优势主要是将对象的创建和管理和业务逻辑分离开,主打一个低耦合,让程序本身更易于维护和管理,比如在我们的项目中,连接数据库的创建和管理只需要交给 Spring 容器就行,业务逻辑在 Service层完成,当需要连接另一个数据库,只需要修改 Spring 的配置文件即可。
为什么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实例化 beanxml 配置
需要先配置一个工厂 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初始化方法使用bean
关闭 / 销毁容器
bean销毁方法
BeanNameAware等 aware 接口,则执行 aware 注入InitializingBean接口的afterPropertiesSet()方法或通过init-method属性指定的方法BeanPostProcessor进行进一步处理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的销毁回调方法
工作原理
ApplicationContext 的 close() 方法@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();
}
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。