FactoryBean

这是一个由在{@link BeanFactory}中使用的对象所实现的接口,它们本身就是用于创建个别对象的工厂。当一个bean实现了这个接口时,它表明它不是一个直接暴露的常规bean实例,而是用于创建和暴露另一个对象的工厂。

实现了这个接口的bean不能被作为普通的bean使用。FactoryBean在定义时遵循了bean的形式,但是对于 bean 引用 (通过调用 ​getObject()​),始终暴露的是由 FactoryBean 创建的对象本身。

FactoryBean可以支持单例和原型两种作用域,同时可以按需延迟创建对象或在启动时立即创建。通过实现{@link SmartFactoryBean}接口,还可以提供更精细的行为元数据信息。

该接口在Spring框架内部被广泛使用,例如在AOP中的{@link org.springframework.aop.framework.ProxyFactoryBean}或{@link org.springframework.jndi.JndiObjectFactoryBean}中。它也可以用于自定义组件,但这通常更适用于基础架构代码。

在Spring框架的核心功能中,FactoryBean被用于以下目的:

  • 使用代理模式创建AOP代理对象:AOP代理的创建依赖于 ​ProxyFactoryBean​,通过实现FactoryBean来封装代理对象的创建逻辑。
  • 与JNDI整合:Spring使得与Java命名和目录接口(JNDI)进行集成的过程更加简化。​JndiObjectFactoryBean​作为一个FactoryBean被使用,它能够管理JNDI对象的查找和暴露。
  • 集成其他基础设施相关组件:比如与缓存、事务管理或消息队列等相关的组件,为了更好地集成和适配,可能会自定义FactoryBean。

FactoryBean是一个以编程方式定义的契约(contract)。实现类不应依赖于注解驱动的注入或其他反射机制。在引导过程中,对 ​getObjectType()​和 ​getObject()​方法的调用可能会比任何后处理器的设置更早进行。如果你需要访问其他的bean,请实现 ​BeanFactoryAware​接口并以编程方式获取它们。

容器只负责管理FactoryBean实例的生命周期,而不负责管理FactoryBean创建的对象的生命周期。因此,容器不会自动调用暴露的bean对象上的销毁方法(例如 ​java.io.Closeable#close()​)。相反,FactoryBean应该实现 ​DisposableBean​接口,并将任何关闭的调用委托给底层对象。

FactoryBean对象参与包含的BeanFactory的bean创建同步。通常除了FactoryBean本身(或类似情况)需要进行懒初始化之外,通常不需要进行内部同步。

public interface FactoryBean<T> {}

这是一个属性的名称,可以在 ​org.springframework.beans.factory.config.BeanDefinition​上通过 ​org.springframework.core.AttributeAccessor#setAttribute​方法设置。当无法从工厂Bean类中推断出对象类型时,工厂Bean可以使用该属性来表明其对象类型。

String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";

该方法返回由此工厂管理的对象的实例(可能是共享的或独立的)。与`BeanFactory`类似,这允许支持单例和原型的设计模式。如果在调用时该FactoryBean尚未完全初始化(例如因为它涉及循环引用),则抛出相应的`FactoryBeanNotInitializedException`异常。从Spring 2.0版本开始,FactoryBean被允许返回`null`对象。在这种情况下,容器将会将其视为正常值使用,不再抛出`FactoryBeanNotInitializedException`异常。现在鼓励FactoryBean实现根据需要自行抛出`FactoryBeanNotInitializedException`。

@Nullable
	T getObject() throws Exception;

返回此FactoryBean创建的对象的类型,如果提前无法确定,则返回null。这使得我们可以在不实例化对象的情况下检查特定类型的bean,例如在自动装配中。对于创建单例对象的实现,应尽量避免创建单例;而是预先估计对象的类型。对于原型对象,在这里返回一个有意义的类型也是可取的。此方法可以在此FactoryBean完全初始化之前调用。它不应依赖于初始化期间创建的状态;当然,如果存在这样的状态,仍然可以使用它。

注意: 自动装配会忽略返回null的FactoryBean。因此,强烈建议正确实现此方法,使用当前FactoryBean的状态。

@Nullable
	Class<?> getObjectType();

如果FactoryBean表明它持有一个单例对象,那么从 ​getObject()​方法返回的对象可能会被所属的BeanFactory缓存。因此,除非FactoryBean始终公开相同的引用,否则不应返回true。

FactoryBean本身的单例状态通常由所属的BeanFactory提供;通常,它必须在那里定义为单例。

注意:此方法返回false并不必然意味着返回的对象是独立的实例。扩展了SmartFactoryBean接口的实现可以通过其SmartFactoryBean#isPrototype()方法显式地指示独立实例。如果FactoryBean的isSingleton()方法返回false,并且它没有实现此扩展接口的话,则普通的FactoryBean实现被默认假设为总是返回独立的实例。

默认实现返回true,因为FactoryBean通常管理单例实例。

default boolean isSingleton() {
		return true;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值