赞
踩
在 Spring 中,Bean 是一个由 Spring IoC(控制反转)容器管理的对象。Bean 通常通过在 XML 配置文件、Java 配置类或基于注解的方式定义,并由容器负责创建和配置。Spring 容器负责管理 Bean 的整个生命周期,从创建、配置到销毁。这种管理包括依赖注入、生命周期回调等。
<bean id="bookDao" class="space.mora.dao.impl.BookDaoImpl"/>
<bean id="bookService" name="service service2" class="space.mora.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao"/> <!--配置依赖 name是指class中的属性名称,ref是指依赖bean的id -->
</bean>
<bean>
标签的name
属性可以用来指定bean的别名,别名之间可以使用逗号、分号、空格进行分割,定义的别名可以用于API获取bean,以及XML中其他地方对该bean进行引用。
Spring通过<bean>
标签声明的bean默认为单例,即只创建一个对象。
如何创建以非单例的形式来创建bean?
<bean>
标签的scope
属性,设置为prototype
(默认为singleton
),若如此,创建的bean每次getBean时拿到的是不同的对象。默认情况下,所有bean在IOC容器启动之后即被创建。
但是,当<bean>
的属性lazy-init
被设置为true
(启用懒加载),或者scope
被设置为prototype
时(非单例),这些对象只有被使用到的时候才会创建ctx.getBean(...)
。
使用无参构造
直接使用普通的<bean>
标签创建时,使用无参构造函数创建类实例。且无论该无参构造的访问控制属性,即便是private也可成功调用,这是因为底层实现借助了反射
机制。请注意必须提供无参构造,否则抛BeanCreationException
。
使用静态工厂
<bean>
标签的class属性指向静态工厂类,额外配置factory-method
属性说明工厂方法名即可。
<bean id="orderDao2" class="space.mora.factory.OrderDaoFactory" factory-method="getOrderDao"/>
<bean id="userDaoFactory" class="space.mora.factory.UserDaoFactory"/>
<bean id="userDao1" factory-bean="userDaoFactory" factory-method="getUserDao"/>
工厂类实现FactoryBean
接口,可一步到位完成配置。该接口配置如下:
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception; // 创建对象并返回
@Nullable
Class<?> getObjectType(); // 返回被创建对象的类class
default boolean isSingleton() {
return true; // 控制是否单例
}
}
Tips
: 容器只负责管理 FactoryBean 实例的生命周期,而不负责管理由 FactoryBean 创建的对象的生命周期。因此,不会自动调用公开的 bean 对象(例如 Closeable.close ())上的销毁方法。相反,FactoryBean 应该实现 DisposableBean,并将任何此类关闭调用委托给底层对象。
使用FactoryBean
后,XML中的<bean>
标签仅需用class指定实现的FactoryBean
非抽象类即可。
<bean id="userDao2" class="space.mora.factory.UserDaoFactoryBean"/>
注意:使用普通实例工厂,Bean实例化默认在IOC容器启动时;而使用FactoryBean
实例化Bean时,默认在ctx.getBean
进而调用FactoryBean#getObject()
时,即属于懒加载模式。
Tips
: 当然具体看你FactoryBean
接口怎么实现,如果你在接口类中声明静态实例,在getObject时返回该静态实例,那么此种情况下,也相当于容器启动时创建。
bean生命周期如下:
init-method
destory-method
我们可以借助Bean的生命周期回调来控制Bean在属性设置完成以及销毁前的行为。主要有以下两种形式:
<bean>
标签的init-method
属性和destory-method
属性,指定初始化回调和销毁回调。需要注意的是,销毁回调函数只有当ClassPathXmlApplicationContext
的close
方法被调用时,才会进行回调。而通常情况下,我们引用容器实例的ApplicationContext
属于上层接口,没有close
方法。因此,想要销毁回调正常被调用的话,首先需要用ClassPathXmlApplicationContext
去引用容器实例,然后
close
关闭容器registerShutdownHook
方法注册销毁回调钩子
。除了使用钩子外,还可以实现Spring的生命周期回调接口中的方法配置回调。
实例化回调可以实现InitializingBean
接口中的afterPropertiesSet
方法。
销毁回调可以实现DisposableBean
接口中的destroy
方法。
当然,这种方式配置的回调仍然需要关闭容器或注册销毁钩子。
Tips
: Spring官方文档并不建议用这种方式,因为这会破坏Spring的非侵入特性。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。