二战spring_FactoryBean

本文解析Spring框架中FactoryBean的工作原理,包括beanName转换、缓存机制、getObject流程和后置处理器。重点讲解如何通过FactoryBean创建自定义bean和其在bean管理中的角色。
摘要由CSDN通过智能技术生成

简介

FactoryBean 也是spring 所管理的bean,允许用户自定义返回的bean对象
spring获取bean核心方法就是doGetBean,那么就从这里为入口开始分析

以下代码为了控制篇幅,有可能会进行删减

doGetBean

	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
		final String beanName = transformedBeanName(name);
		Object sharedInstance = getSingleton(beanName);//从单例池里里面获取FactoryBean对象
		if (sharedInstance != null && args == null) {
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		...
	}

transformedBeanName(name)

	String FACTORY_BEAN_PREFIX = "&";
	public static String transformedBeanName(String name) {
		String beanName = name;
		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
		}
		return beanName;
	}

可以看到,这里判读是否为&开头,如果是以&开头,就会截掉&,然后返回beanName
这个&的作用就是用于判断用户是想获取FactoryBean本身还是想获取FactoryBean返回的Bean

	public String canonicalName(String name) {
		String canonicalName = name;
		String resolvedName;
		do {
			resolvedName = this.aliasMap.get(canonicalName);
			if (resolvedName != null) {
				canonicalName = resolvedName;
			}
		}
		while (resolvedName != null);
		return canonicalName;
	}

对返回的BeanName进行判断是否存在,这里可以看到aliasMap,很明显和这个map和别名相关,这里也这是进行别名转换的逻辑了

getObjectForBeanInstance

	protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// !!! 
		if (mbd == null && containsBeanDefinition(beanName)) {
			mbd = getMergedLocalBeanDefinition(beanName);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		return object;
	}

这里可以看到对刚才从单例池里获取bean 进行了强转

	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		synchronized (getSingletonMutex()) {
			Object object = this.factoryBeanObjectCache.get(beanName);
			if (object == null) {
				object = doGetObjectFromFactoryBean(factory, beanName);
				Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
				if (alreadyThere != null) {
					object = alreadyThere;
				}
				else {
					object = postProcessObjectFromFactoryBean(object, beanName);	
					this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
				}
			}
			return (object != NULL_OBJECT ? object : null);
		}
		
	}

这里的factoryBeanObjectCache 是一个缓存,第一次获取一般是没有的,真正获取bean的逻辑在doGetObjectFromFactoryBean
这个方法比较简单就不贴代码了,能在方法里面清楚的看到调用FactoryBean的getObject 方法

在这里插入图片描述
这里再关注一下postProcessObjectFromFactoryBean(…) 这个方法,这里会回调后置处理器,不过默认这些逻辑没有做任何处理

最后就是将这个对象添加到缓存,下次获取的时候直接从缓存获取,然后就返回了

总结

1.对beanName进行转换
2.转换后先从缓存里面尝试获取
3.获取不到就调用getObject方法
4.调用后置处理器的postProcessAfterInitialization
5.添加缓存,结果返回

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值