FactoryBean
public interface FactoryBean<T> {
//获取对象
T getObject() throws Exception;
//获取对象类型
Class<?> getObjectType();
//是否单例,默认true
default boolean isSingleton() {
return true;
}
}
FactoryBean是一种特殊的bean,本身又是个工厂,实现了FactoryBean的bean会被注册到容器中。
ObjectFactory
public interface ObjectFactory<T> {
//获取对象
T getObject() throws BeansException;
}
ObjectFactory就是个对象工厂。
示例对比
public class Cat {
public Cat() {
System.out.println("调用了Cat构造器");
}
}
@Component
public class MyFactoryBean implements FactoryBean<Dog> {
@Override
public Dog getObject() throws Exception {
return new Dog();
}
@Override
public Class<?> getObjectType() {
return Dog.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
MyFactoryBean用来生成Dog对象。
public class Cat {
public Cat() {
System.out.println("调用了Cat构造器");
}
}
@Component
public class MyObjectFactory implements ObjectFactory<Cat> {
@Override
public Cat getObject() throws BeansException {
return new Cat();
}
}
MyObjectFactory用来生成Cat对象。
System.out.println(ctx.getBean("myFactoryBean"));
System.out.println(ctx.getBean("myFactoryBean"));
System.out.println(ctx.getBean("&myFactoryBean"));
System.out.println(((MyObjectFactory)ctx.getBean("myObjectFactory")).getObject());
//输出:
调用了Dog构造器
com.brain.demo.factory.Dog@58c1da09
com.brain.demo.factory.Dog@58c1da09
com.brain.demo.factory.MyFactoryBean@2b2954e1
调用了Cat构造器
com.brain.demo.factory.Cat@58d6e55a
ObjectFactory没啥说的,就是对象工厂,通过getObject获取对象。
重点看下FactoryBean。MyFactoryBean本身作为bean(“myFactoryBean”)被扫描进容器中,即singletonObjects。当通过getBean或者@Autowired等方式需要获得bean时,调用getObject或者从缓存中获取所需的对象。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//名称转换
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
//这个地方获得到bean("myFactoryBean")
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//这里进行了转换
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
}
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//判断name是否是&开头的,代表是FactoryBean
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
//不是FactoryBean,就是普通的bean,返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//调用FactoryBean的getObject方法获取bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
protected Object getCachedObjectForFactoryBean(String beanName) {
//factoryBeanObjectCache就是用来存放FactoryBean getObject生成的对象,此时还不包含我们需要的bean
return this.factoryBeanObjectCache.get(beanName);
}
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//单例且singletonObjects中已经加载了FactoryBean
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
//第一次进来是获取不到的
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//调用getObject,此时生成了Dog实例,打印“调用了Dog构造器”
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
//调用postProcessAfterInitialization,如果有AOP,此时生成代理对象
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//将Dog放到缓存中,下次就可以取到了
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
而要获取MyFactoryBean就要通过“&myFactoryBean”才能获取,getObjectForBeanInstance时通过BeanFactoryUtils.isFactoryDereference判断beanName是不是以&开头的,如果是,并且是FactoryBean类型的,则直接返回。
总结
- FactoryBean本身作为bean保存在
singletonObjects
,beanName和普通bean一样,首字母小写(如果你没指定的话)。 - 如果直接通过beanName获取到的是FactoryBean通过getObject生成的对象,生成的对象保存在
factoryBeanObjectCache
中,便于下次获取时不用再调用getObject。 - 如果想获取FactoryBean本身,需要通过
&beanName
来获取,容器根据前缀&和是否是FactoryBean
,来从singletonObjects中获取bean。 - ObjectFactory是一个普通工程,通过getObject生成对象,不会像上面进行缓存。