使用FactoryBean接口实现自定义bean初始化
本文所要介绍的FactoryBean是Spring中定义的一个接口,当把它的实现类定义为BeanFactory中的一个bean,我们在获取其对应的bean时实际上获取的是FactoryBean所包含的那个对象,而不是它本身。我们先来看一下FactoryBean的定义。
public interface FactoryBean<T> { /** * 获取实际要返回的bean对象。 * @return * @throws Exception */ T getObject() throws Exception; /** * 获取返回的对象类型 * @return */ Class<?> getObjectType(); /** * 是否单例 * @return */ boolean isSingleton(); }
我们可以看到FactoryBean是使用了泛型的,表示其对应产生的Bean是什么类型的对象。我们来看一个实现。
public class UserFactoryBean implements FactoryBean<User> { private User user; @Override public User getObject() throws Exception { if (user == null) { synchronized (this) { if (user == null) { User user = new User(); user.setId(1); user.setName("张三"); this.user = user; } } } returnuser; } @Override public Class<?> getObjectType() { return User.class; } @Override public boolean isSingleton() { return true; } }
上面代码中定义了一个UserFactoryBean,用以产生一个单例的User对象。可以看到,我们在getObject()方法中使用了同步块来保证产生的bean永远是同一个对象。其实这个并不是必须的。在初始化时BeanFactory调用FactoryBean创建bean时就是同步的,而且BeanFactory创建bean时默认是单例的,也就意味着FactoryBean的getObject方法在BeanFactory中定义为单例的时候只会调用一次。但有一种情况例外,那就是如果定义bean时指定了“lazy-init=true”时,那就意味着该bean只有在用到的时候才会进行初始化,这个时候如果刚好两个线程同时需要使用,就会出现在两个线程中同时调用FactoryBean的getObject方法进行bean的初始化,如不加控制就会出现两个实例。为保证只有一个实例,getObject方法内部需要是同步的。
此外,需要注意的是FactoryBean的isSingleton方法返回结果表示当前FactoryBean产生的bean是否是单例形式,即每次请求getObject()方法返回的是否都是同一个bean对象。其实FactoryBean更多的是在Spring内部使用,isSingleton只是用来表示当前返回的bean对象是否可以用BeanFactory缓存的一个标志。
上面示例对象的Spring配置文件如下:
<bean id="userFactoryBean" class="com.xxx.spring.factorybean.UserFactoryBean" lazy-init="false"/>
对于一个FactoryBean接口实现类定义的bean其实Spring将实例化两个bean,一个是FactoryBean本身对应的bean,另一个是FactoryBean产生的对象对应的bean。所以当我们在通过注解方式注入一个FactoryBean实例对应的bean时,既可以把它当做一个FactoryBean进行注入,也可以把它当做一个对应产生的实例进行注入。而如果是自己直接从ApplicationContext中获取的话,则直接通过FactoryBean实现类定义的bean名称获取到的是FactoryBean实现类产生的对象。如在上面示例中,如果我们通过ApplicationContext的getBean(“userFactoryBean”)获取到的就将是对应产生的User对象,如果我们需要获取到对应的FactoryBean本身,则可以在对应的FactoryBean实现类定义的bean名称前加上“&”进行获取,如上如果我们要获取到UserFactoryBean本身,则可以通过ApplicationContext的getBean(“&userFactoryBean”)。如果是通过类型获取,就可以直接通过User类型或者UserFactoryBean类型获取到对应的bean对象了。
(注:本文是基于Spring3.1.0所写)
相关推荐
在Spring框架中,`FactoryBean`接口是一个非常重要的组件,它允许我们自定义Bean的创建逻辑,这在处理复杂对象的实例化或者需要特定初始化步骤时尤其有用。本笔记将详细探讨如何通过实现`FactoryBean`接口来创建Bean...
在本篇文章中,我们将深入探讨Spring源码中关于Bean初始化的过程,特别是`finishBeanFactoryInitialization()`方法和`preInstantiateSingletons()`方法。 首先,`finishBeanFactoryInitialization(Confi...
这样,我们可以在`getObject()`方法中实现复杂的逻辑,如初始化、依赖注入等。 首先,我们需要了解`FactoryBean`接口的基本结构。它主要有两个核心方法: 1. `Object getObject() throws Exception;` 这个方法...
9. **FactoryBean**:Spring的`FactoryBean`允许自定义Bean的创建方式。`FactoryBean`创建的对象被视为容器中的单个Bean,因此,它的实例化顺序遵循标准规则。 综上所述,Spring Bean的实例化顺序是一个复杂的过程...
3. **自定义类型转换**:当Spring需要将一个Bean的属性值转换为另一个类型时,可以使用FactoryBean来实现自定义的转换逻辑。 4. **第三方库集成**:某些库可能不支持Spring的依赖注入,或者它们的API需要特殊的初始...
1. **延迟初始化**: Spring容器在遇到`FactoryBean`时,不会立即创建bean,而是在需要该bean时才通过`getObject()`方法进行实例化,这实现了对象的延迟初始化。 2. **类型转换**: Spring会根据`getObjectType()`返回...
例如,如果我们有一个复杂的对象需要在创建时执行特定的步骤,或者需要延迟初始化,那么使用FactoryBean就非常合适。 FactoryBean的应用场景主要包括: - 创建JDBC连接池,如C3P0、DBCP等,这些连接池可以通过...
在Spring框架中,`FactoryBean`是一个非常关键的接口,它允许我们自定义对象的创建方式,这在处理复杂依赖关系或需要特殊初始化逻辑时尤为有用。本篇将通过一个测试代码示例来深入解析`FactoryBean`的工作原理及其在...
`FactoryBean`的使用使得我们可以控制对象的创建过程,甚至可以在对象被Spring管理的同时,添加额外的初始化或者装配步骤。在这个"FactoryBean.zip"中,很可能是包含了关于如何使用`FactoryBean`来实现特定功能的...
这个接口使得我们可以实现自己的工厂逻辑,返回一个完全初始化、配置好的对象,甚至可以是带有额外增强功能的对象,比如代理类。在标题“spring的FactoryBean增强我们的目标对象.rar”中,提到的核心概念就是如何...
4. **容器回调**:在Bean初始化之后,Spring容器可能会调用自己的回调方法,如`BeanPostProcessor`接口实现的`postProcessBeforeInitialization()`和`postProcessAfterInitialization()`方法,允许自定义逻辑进一步...
在Spring框架中,Bean的生命周期管理和作用域是其核心特性之一,它们对于理解Spring如何管理对象的创建、初始化、使用以及销毁至关重要。首先,我们来深入探讨Bean的生命周期。 Spring中的Bean生命周期主要分为两个...
`FactoryBean`接口允许开发者自定义Bean的实例化过程。通过实现`getObject()`方法,我们可以控制Spring容器加载我们期望的Bean。这个接口特别适用于那些需要特殊初始化逻辑或非标准实例化的对象。 6. **...
通过实现FactoryBean接口,你可以控制实例化对象的具体过程,包括任何复杂的依赖注入或者初始化步骤。例如,如果你有一个数据库连接池,可能需要在创建连接时进行配置,这时可以使用FactoryBean来创建和配置这些连接...
而传统的`factoryBean`则是通过实现`FactoryBean`接口来创建bean,这提供了更大的灵活性,但使用起来相对复杂。 结合`@Service`注解,它是Spring Data JPA和其他服务层组件常用的注解。`@Service`通常用于标记业务...
除了这些基本的Bean配置,Spring还提供了许多高级功能,如Prototype作用域(每次请求创建新的Bean实例)、Lazy初始化(只有在实际使用时才初始化Bean)、FactoryBean(用于自定义Bean的创建逻辑)等。此外,Bean后...
最后,Spring提供了一种更灵活的机制——`BeanPostProcessor`接口,它允许在bean初始化前后进行拦截和处理。`BeanPostProcessor`有两个关键方法:`postProcessBeforeInitialization()`和`...
`InitializingBean`和`DisposableBean`接口分别提供了`afterPropertiesSet()`和`destroy()`方法,使得开发者能够自定义Bean的初始化和销毁逻辑。 - 使用`@PostConstruct`和`@PreDestroy`注解也能实现相同功能,这两...
3. `FactoryBean`允许自定义Bean的创建逻辑,`AbstractBeanFactory`在获取Bean时会检查是否是FactoryBean并调用其`getObject()`方法。 4. `BeanPostProcessor`可以定制Bean实例化后的处理,`...
关于FactoryBean的使用,它允许我们创建具有复杂生命周期和初始化逻辑的bean。在自定义标签的场景中,我们可能希望对从标签中获取的内容进行额外的处理或包装。FactoryBean可以通过`getObject()`方法返回最终的bean...