你有没有听说过Spring的FactoryBean呀?很多框架的灵活替换全靠他啦!!

1 什么是 FactoryBean接口?

很多同学都知道BeanFactory接口,这个是大名鼎鼎的Spring中的核心接口,IOC的根本所在。而这个FactoryBean的作用是用来创建一类bean,它的源代码是这样的:

public interface FactoryBean<T> {
  // 获取 ObjectType 的一个对象
 	T getObject() throws Exception;
  
  // 当前实现类所要创建的对象类型
  Class<?> getObjectType();
  
  default boolean isSingleton() {
		return true;
	}
}

FactoryBean演示

上面这个图可以很简单的去概括这个接口的作用,就是要一个对象,然后给一个对象的逻辑。

1.1 小小的深入一点

对于 FactoryBean接口,其实还有一个子接口,叫做SmartFactoryBean

public interface SmartFactoryBean<T> extends FactoryBean<T> {
	// 最核心的一个方法 --> 如果说这里返回 true 那么则会在 Spring容器初始化的时候就将这个Bean实例化
  default boolean isEagerInit() {
		return false;
	}
}

下面这段代码则是对于SmartFactoryBean的迫切加载在Spring中的体现:

// 这段代码来自 DefaultListableBeanFactory -> 922 行
public void preInstantiateSingletons() throws BeansException {
		// 省略部分代码
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
          // 核心点便是这里了
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

	}

1.2 实战一把

对于FactoryBean的使用其实只分为俩步:

  • 实现FactoryBean接口
  • 将实现类注入Bean工厂

下面这段代码来自Easy ES的源码,同理也可以在Mybatis的底层代码中找到类似的设计(对SqlSession的FactoryBean),这样便相当于托管给实现类创建一类Bean的能力

@Component // 注入BeanFactory
public class MapperFactoryBean<T> implements FactoryBean<T> {


    private final Class<T> mapperInterface;

    public MapperFactoryBean(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }

    @Override
    @SuppressWarnings("all")
    public T getObject() throws Exception {
        EsMapperProxy<T> esMapperProxy = new EsMapperProxy<>(mapperInterface);
        return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, esMapperProxy);
    }
		
    // 这个便是这个FactoryBean所要创建的类型
    @Override
    public Class<?> getObjectType() {
        return this.mapperInterface;
    }
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沈自在-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值