FactoryBean简介
FactoryBean 是一个工厂对象,用于创建和管理其他 Bean 的实例。
FactoryBean 接口定义了一种创建 Bean 的方式,它允许开发人员在 Bean 的创建过程中进行更多的自定义操作。
通过实现 FactoryBean 接口,开发人员可以创建复杂的 Bean 实例,或者在 Bean 实例化之前进行一些额外的逻辑处理。
此接口在框架中大量使用,例如用于AOP的org.springframework.AOP.framework.ProxyFactoryBean
或 com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean。
设计模式:
工厂方法。
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
详情见: https://blog.csdn.net/sinat_32502451/article/details/133070351
FactoryBean
源码: org.springframework.beans.factory.FactoryBean
FactoryBean 接口具有以下方法:
-
getObject():返回此工厂管理的对象的实例。
-
getObjectType():返回此FactoryBean创建的对象类型。
-
isSingleton():工厂管理的对象是否为单例。
public interface FactoryBean<T> {
/**
* 返回此工厂管理的对象的实例
*/
@Nullable
T getObject() throws Exception;
/**
* 返回此FactoryBean创建的对象类型
*/
@Nullable
Class<?> getObjectType();
/**
* 这个工厂管理的对象是单例吗?也就是说,getObject() 总是返回相同的对象(可以缓存的引用)吗?
*/
default boolean isSingleton() {
return true;
}
}
AbstractFactoryBean
AbstractFactoryBean 实现了 FactoryBean。
AbstractFactoryBean 是通过 FactoryBean 实现的简单模板超类,根据标志创建单例或原型对象。
/**
* 返回单例实例或创建新的原型实例。
*/
@Override
public final T getObject() throws Exception {
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
else {
return createInstance();
}
}
/**
* 子类必须重写的模板方法,以构造此工厂返回的对象。
*/
protected abstract T createInstance() throws Exception;
@Override
@Nullable
public abstract Class<?> getObjectType();
/**
* 用于销毁单例实例。
*/
protected void destroyInstance(@Nullable T instance) throws Exception {
}
ListFactoryBean
ListFactoryBean 继承了 AbstractFactoryBean。间接实现了 FactoryBean。
ListFactoryBean 是 List实例的简单工厂。允许通过XML bean定义中的“list”元素集中设置列表。
ListFactoryBean 重写了 createInstance(),用于返回 List 类型的数据。
/**
* 重写了 createInstance(),用于返回 List 类型的数据
*
*/
protected List<Object> createInstance() {
if (this.sourceList == null) {
throw new IllegalArgumentException("'sourceList' is required");
}
List<Object> result = null;
if (this.targetListClass != null) {
result = BeanUtils.instantiateClass(this.targetListClass);
}
else {
result = new ArrayList<>(this.sourceList.size());
}
Class<?> valueType = null;
if (this.targetListClass != null) {
valueType = ResolvableType.forClass(this.targetListClass).asCollection().resolveGeneric();
}
if (valueType != null) {
TypeConverter converter = getBeanTypeConverter();
for (Object elem : this.sourceList) {
result.add(converter.convertIfNecessary(elem, valueType));
}
}
else {
result.addAll(this.sourceList);
}
return result;
}
ProxyFactoryBean
源码:org.springframework.aop.framework.ProxyFactoryBean
ProxyFactoryBean 由FactoryBean实现,在Spring BeanFactory中基于bean构建AOP代理。
/**
* 返回代理。当客户端从该工厂bean获取bean时调用。
* 创建此工厂返回的AOP代理的实例。该实例将被缓存为单例,并在每次调用 getObject() 时创建代理。
*/
@Override
@Nullable
public Object getObject() throws BeansException {
//初始化切面的责任链
initializeAdvisorChain();
if (isSingleton()) {
//获取单例对象
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
//获取原型对象
return newPrototypeInstance();
}
}
MybatisSqlSessionFactoryBean
这个类,是mybatis常用配置的类。
源码:com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean
可以看到,在实例化bean对象(此处为SqlSessionFactory )时, 会读取配置的值,才构建sqlSessionFactory。
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
//在返回实例化对象之前的逻辑
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
@Override
public void afterPropertiesSet() throws Exception {
notNull(dataSource, "SFunction 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "SFunction 'sqlSessionFactoryBuilder' is required");
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"SFunction 'configuration' and 'configLocation' can not specified with together");
// 这里会读取配置的值,构建sqlSessionFactory
this.sqlSessionFactory = buildSqlSessionFactory();
}
参考资料:
https://blog.csdn.net/belongtocode/article/details/134631544
标签:FactoryBean,return,实例,--,Spring,源码,单例,null,throws From: https://www.cnblogs.com/expiator/p/18393752