7.FactoryBean 和BeanFactory去区别

时间:2022-09-08 21:19:29

FactoryBean源码:

/*
* Copyright 2002-2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.beans.factory;

/**
* Interface to be implemented by objects used within a {
@link BeanFactory}
* which are themselves factories. If a bean implements this interface,
* it is used as a factory for an object to expose, not directly as a bean
* instance that will be exposed itself.
*
* <p><b>NB: A bean that implements this interface cannot be used as a
* normal bean.</b> A FactoryBean is defined in a bean style, but the
* object exposed for bean references ({
@link #getObject()} is always
* the object that it creates.
*
* <p>FactoryBeans can support singletons and prototypes, and can
* either create objects lazily on demand or eagerly on startup.
* The {
@link SmartFactoryBean} interface allows for exposing
* more fine-grained behavioral metadata.
*
* <p>This interface is heavily used within the framework itself, for
* example for the AOP {
@link org.springframework.aop.framework.ProxyFactoryBean}
* or the {
@link org.springframework.jndi.JndiObjectFactoryBean}.
* It can be used for application components as well; however,
* this is not common outside of infrastructure code.
*
* <p><b>NOTE:</b> FactoryBean objects participate in the containing
* BeanFactory's synchronization of bean creation. There is usually no
* need for internal synchronization other than for purposes of lazy
* initialization within the FactoryBean itself (or the like).
*
*
@author Rod Johnson
*
@author Juergen Hoeller
*
@since 08.03.2003
*
@see org.springframework.beans.factory.BeanFactory
*
@see org.springframework.aop.framework.ProxyFactoryBean
*
@see org.springframework.jndi.JndiObjectFactoryBean
*/
public interface FactoryBean<T> {

/**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
* <p>As with a {
@link BeanFactory}, this allows support for both the
* Singleton and Prototype design pattern.
* <p>If this FactoryBean is not fully initialized yet at the time of
* the call (for example because it is involved in a circular reference),
* throw a corresponding {
@link FactoryBeanNotInitializedException}.
* <p>As of Spring 2.0, FactoryBeans are allowed to return {
@code null}
* objects. The factory will consider this as normal value to be used; it
* will not throw a FactoryBeanNotInitializedException in this case anymore.
* FactoryBean implementations are encouraged to throw
* FactoryBeanNotInitializedException themselves now, as appropriate.
*
@return an instance of the bean (can be {@code null})
*
@throws Exception in case of creation errors
*
@see FactoryBeanNotInitializedException
*/
T getObject()
throws Exception;

/**
* Return the type of object that this FactoryBean creates,
* or {
@code null} if not known in advance.
* <p>This allows one to check for specific types of beans without
* instantiating objects, for example on autowiring.
* <p>In the case of implementations that are creating a singleton object,
* this method should try to avoid singleton creation as far as possible;
* it should rather estimate the type in advance.
* For prototypes, returning a meaningful type here is advisable too.
* <p>This method can be called <i>before</i> this FactoryBean has
* been fully initialized. It must not rely on state created during
* initialization; of course, it can still use such state if available.
* <p><b>NOTE:</b> Autowiring will simply ignore FactoryBeans that return
* {
@code null} here. Therefore it is highly recommended to implement
* this method properly, using the current state of the FactoryBean.
*
@return the type of object that this FactoryBean creates,
* or {
@code null} if not known at the time of the call
*
@see ListableBeanFactory#getBeansOfType
*/
Class
<?> getObjectType();

/**
* Is the object managed by this factory a singleton? That is,
* will {
@link #getObject()} always return the same object
* (a reference that can be cached)?
* <p><b>NOTE:</b> If a FactoryBean indicates to hold a singleton object,
* the object returned from {
@code getObject()} might get cached
* by the owning BeanFactory. Hence, do not return {
@code true}
* unless the FactoryBean always exposes the same reference.
* <p>The singleton status of the FactoryBean itself will generally
* be provided by the owning BeanFactory; usually, it has to be
* defined as singleton there.
* <p><b>NOTE:</b> This method returning {
@code false} does not
* necessarily indicate that returned objects are independent instances.
* An implementation of the extended {
@link SmartFactoryBean} interface
* may explicitly indicate independent instances through its
* {
@link SmartFactoryBean#isPrototype()} method. Plain {@link FactoryBean}
* implementations which do not implement this extended interface are
* simply assumed to always return independent instances if the
* {
@code isSingleton()} implementation returns {@code false}.
*
@return whether the exposed object is a singleton
*
@see #getObject()
*
@see SmartFactoryBean#isPrototype()
*/
boolean isSingleton();

}

BeanFactory在前面介绍过,

BeanFacotry是一个类工厂,使用它来创建各种类型的Bean,最主要的方法就是getBean(String beanName),该方法从容器中返回特定名称的Bean,只不过其中有一种Bean是FacotryBean.

一个Bean 要想成为FacotryBean,必须实现FactoryBean 这个接口。

FactoryBean定义了三个接口方法:

    1)Object getObject():返回由FactoryBean创建的Bean的实例,如果isSingleton()方法返回true,是单例的实例,该实例将放入Spring的缓冲池中;

    2)boolean isSingleton*():确定由FactoryBean创建的Bean的作用域是singleton还是prototype;

    3) getObjectType():返回FactoryBean创建的Bean的类型。

FactoryBean 是一直特殊的bean,它实际上也是一个工厂,我们在通过FactoryBeanName得到的Bean,是FacotryBean创建的Bean,即它通过getObject()创建的Bean.我们要想得到FactoryBean本身,必须通过&FactoryBeanName得到,即在BeanFactory中通过getBean(&FactoryBeanName)来得到 FactoryBean

注:在spring 中是通过BeanFactoryUtils.isFactoryDereference()来判断一个Bean是否是FactoryBean.

spring 内部实现中应该是在通过BeanFacotry 的getBean(String beanName) 来得到Bean时,如果这个Bean是一个FactoryBean,则把它生成的Bean返回,否者直接返回Bean.