当前位置 : 主页 > 编程语言 > java >

让你真正的理解BeanFactory 与 FactoryBean的区别

来源:互联网 收集:自由互联 发布时间:2022-07-13
文章目录 ​​1.BeanFactory​​ ​​1.1.概念​​ ​​1.2.源码​​ ​​2.FactoryBean​​ ​​2.1.概念​​ ​​2.2.源码​​ ​​3.BeanFactory与FactoryBean的区别​​ ​​4.FactoryBean实现案例:Sq


文章目录

  • ​​1.BeanFactory​​
  • ​​1.1.概念​​
  • ​​1.2.源码​​
  • ​​2.FactoryBean​​
  • ​​2.1.概念​​
  • ​​2.2.源码​​
  • ​​3.BeanFactory与FactoryBean的区别​​
  • ​​4.FactoryBean实现案例:SqlSessionFactoryBean​​
  • ​​4.1.重要代码片段​​
  • ​​4.2.源码解读​​

1.BeanFactory

1.1.概念

1.BeanFactory本质上不是Bean,它是加载Bean的工厂;
2.BeanFactory从字面意义上看,是以Factory结尾的,所以我们理解为“Bean的一个工厂类”
3.作用:工厂类的行为和功能做了一个定义
BeanFactory是Spring Bean工厂的顶级工厂接口,其他的工厂类都是实现该类,根据具体的需求做扩展
因此,可以认为BeanFactory只是对工厂类的行为和功能做了一个定义;

1.2.源码

package org.springframework.beans.factory;

import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;

/*
* BeanFactory 接口是 Spring 框架中的核 心接口,它是工厂模式的具体实现。
* BeanFactory 使用控制反转对应用程序的配置和依赖性规范与实际 的应用程序代码进行了分离。
* 但 BeanFactory 容器实例化后并不会自动实例化 Bean,只有当 Bean 被 使用时 BeanFactory 容器才会对该Bean 进行实例化与依赖关系的装配。
*
*/
public interface BeanFactory {
//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&";

//根据bean的名字,获取在IOC容器中得到bean实例
Object getBean(String name) throws BeansException;

//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。
<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

//提供对bean的检索,看看是否在IOC容器有这个名字的bean
boolean containsBean(String name);

//根据bean名字得到bean实例,并同时判断这个bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

//得到bean实例的Class类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

//得到bean的别名,如果根据别名检索,那么其原名也会被检索出来
String[] getAliases(String name);

}

2.FactoryBean

2.1.概念

1.FactoryBean本质上它是IOC容器中的一个Bean;
2.FactoryBean在此基础上还有另外一个功能:能够作为Bean的工厂,来产生一个Bean对象;
3.作用是:产生其他bean实例。
通常情况下,这种bean没有什么特别的要求,仅需要提供一个工厂方法,该方法用来返回其他bean实例。
由工厂bean产生的其他bean实例,不再由Spring容器产生,因此与普通 bean的配置不同,不再需要提供class元素。

2.2.源码

package org.springframework.beans.factory;

import org.springframework.lang.Nullable;

/**
* FactoryBean是Spring内部实现的一种规范用&开头作为BeanName
* Spring中所有的容器都是FactoryBean
* 因为容器本身由容器管理,root来创建
*
*/
//工厂Bean,用于产生其他对象
public interface FactoryBean<T> {


//获取容器管理的对象实例
@Nullable
T getObject() throws Exception;

//获取Bean工厂创建的对象的类型
@Nullable
Class<?> getObjectType();

//Bean工厂创建的对象是否是单态模式,如果是单态模式,则整个容器中只有一个实例
//对象,每次请求都返回同一个实例对象
default boolean isSingleton() {
return true;
}

}

3.BeanFactory与FactoryBean的区别

4.FactoryBean实现案例:SqlSessionFactoryBean

4.1.重要代码片段

package org.mybatis.spring;

/**
* 我们这里SqlSessionFactoryBean 理解为主要是为了生成SqlSessionFactory对象实例的即可 方法:buildSqlSessionFactory()
*/
public class SqlSessionFactoryBean
implements
//主要是实现其getObject方法
FactoryBean<SqlSessionFactory>,
//主要是实现了afterPropertiesSet方法
InitializingBean,
ApplicationListener<ApplicationEvent> {

private SqlSessionFactory sqlSessionFactory;

/**
* 这里主要是是加载mybatis的相关配置
*/
@Override
public void afterPropertiesSet() throws Exception {
notNull(dataSource, "Property 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"Property 'configuration' and 'configLocation' can not specified with together");

this.sqlSessionFactory = buildSqlSessionFactory();
}

/**
* 配置样例
* <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
* <property name="configLocation" value="classpath:mybatis-config.xml"></property>
* <property name="mapperLocations" value="classpath:mapper/*.xml"></property>
* <property name="dataSource" ref="dataSource"/>
* </bean>
*/
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {

。。。。。。
return this.sqlSessionFactoryBuilder.build(targetConfiguration);
}

/**
* {@inheritDoc}
*/
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}

/**
* {@inheritDoc}
*/
@Override
public Class<? extends SqlSessionFactory> getObjectType() {
return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
}

/**
* {@inheritDoc}
*/
@Override
public boolean isSingleton() {
return true;
}
}

4.2.源码解读

1.首先SqlSessionFactoryBean 实现了FactoryBean接口(其中的方法有:getObject(),getObjectType(), isSingleton)
2.通过调用getObject(),会返回sqlSessionFactory对象;

让你真正的理解BeanFactory 与 FactoryBean的区别_ide


上一篇:JUC(8)Java内存模型-JMM和Volatile关键字
下一篇:没有了
网友评论