BeanFactory有3大子接口:ListableBeanFactory
,HierarchicalBeanFactory
,AutowireCapableBeanFactory
如下:
忽略ApplicationContext相关类
1、ListableBeanFactory
通过这个接口,我们可以获取多个 Bean,而最顶层 BeanFactory 接口的方法都是获取单个 Bean的,ApplicationContext 继承了 ListableBeanFactory
2、HierarchicalBeanFactory
这个接口主要是处理BeanFactory的子父级关系,也就是说我们可以在应用中起多个 BeanFactory,然后可以将各个 BeanFactory 设置为父子关系。ApplicationContext 继承了 HierarchicalBeanFactory
3、AutowireCapableBeanFactory
这个接口主要是用来处理Bean的自动装配,ApplicationContext 并没有继承它,ApplicationContext是通过组合的方式来使用它的如果你看到 ApplicationContext 接口定义中的最后一个方法 getAutowireCapableBeanFactory() 就知道了。
看到这里的时候,我觉得读者就应该站在高处看 ApplicationContext 了,ApplicationContext 继承自BeanFactory
但是它不应该被理解为 BeanFactory 的实现类,而是说其内部持有一个实例化的 BeanFactory(DefaultListableBeanFactory)
以后所有的 BeanFactory相关的操作其实是委托给这个实例来处理的
4、DefaultListableBeanFactory
ConfigurableListableBeanFactory
也是一个特殊的接口,看图,特殊之处在于它继承了第二层所有的三个接口,而 ApplicationContext
没有。我们可以看到 ConfigurableListableBeanFactory
只有一个实现类 DefaultListableBeanFactory,而且实现类 DefaultListableBeanFactory
还通过实现右边的 AbstractAutowireCapableBeanFactory
通吃了右路。所以结论就是,最底下这个家伙 DefaultListableBeanFactory
基本上是最牛的 BeanFactory
了,这也是为什么这边会使用这个类来实例化的原因。
DefaultListableBeanFactory父接口有,BeanDefinitionRegistry(bean注册中心),SingletonBeanRegistry(单例bean注册中心),BeanFactory (bean储存中心)。DefaultListableBeanFactory有储存和注册bean的作用,本文重点研究DefaultListableBeanFactory
DefaultListableBeanFactory的属性分布在,其几个父类中,为了方便查看,把他们和在一起
1、储存BeanDefinition
//储存springBean的容器,键是别名,值是BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
//储存springBean名字的容器
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** 从bean名称映射到合并的RootBeanDefinition. */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/** 在冻结配置的情况下缓存的bean定义名称数组 */
private volatile String[] frozenBeanDefinitionNames;
// allowBeanDefinitionOverriding属性是指是否允对一个名字相同但definition不同进行重新注册,默认是true。
private boolean allowBeanDefinitionOverriding = true;
// 当前正在创建的bean的名称
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation");
2、储存和实例化对象
/**创建bean实例的策略。*/
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
//已创建至少一次的bean的名称
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
//是否缓存bean元数据,或者是否为每个访问重新获取它
private boolean cacheBeanMetadata = true;
//是否自动尝试解析bean之间的循环引用
private boolean allowCircularReferences = true
//是否为所有bean缓存bean定义元数据
private volatile boolean configurationFrozen = false;
//是否允许热加载即使是 懒加载设置
private boolean allowEagerClassLoading = true;
//是否在循环引用的情况下使用原始bean实例,即使注入的bean最终被包装了
private boolean allowRawInjectionDespiteWrapping = false;
//当前正在创建的bean的名称
private final Set<String> singletonsCurrentlyInCreation =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//*当前在创建检查中排除的bean的名称
private final Set<String> inCreationCheckExclusions =Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//一次性bean实例:一次性实例的bean名称。
private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
//包含bean名称之间的映射:bean名称到bean包含的一组bean名称
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
//在依赖bean名称之间映射:bean名称到依赖bean名称集
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
//在依赖bean名称之间映射:bean名称到bean依赖项的一组bean名称
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
3、依赖检查和自动连接的忽略
// 依赖接口忽略依赖检查和自动连接,这是类对象的集合。默认情况下,只会忽略BeanFactory接口。(也就是实现了这些接口的Bean,不要Autowired自动装配了)
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
// 依赖类型忽略依赖检查和自动连接,这是类对象的集合:例如,String。默认是没有的。
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>();
ignoredDependencyInterfaces
:忽略自动注入和ASrv中的setter方法入参相同的类
ignoredDependencyTypes
: 忽略自动注入传入XX.Class的类型
这样来看ignoreDependencyType方法的生效范围更广
注:注入方式要求是default-autowire=“byType” 且只影响xml配置自动装配的依赖注入方式
该属性虽然在源码中有使用,但我觉得一般情况下不会用到它,一是因为在使用过程中都希望自动注入依赖,而是因为有@AutoWired注解,可以决定哪些依赖必须注入 , 二是因为目前使用最多最流行的是SpringBoot方式配置bean,xml方式将更少触及.
所以我觉得该方法仅仅在学习源代码时了解即可,不值得深究.
4、从依赖类型映射到对应的自动连接值
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
放在这里面的类,我们可以直接标注@Autowired使用,不用在我们自己注入到容器中;
DefaultListableBeanFactory中有BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext
AnnotationConfigWebApplicationContext中还有ServletRequest,ServletResponse,HttpSession,WebRequest
@Component
public class Demo {
@Autowired
private BeanFactory beanFactory;
public BeanFactory getBeanFactory(){
//可以获取容器使用的BeanFactory对象
return beanFactory;
}
}
5、储存单例对象
//储存单例对象的容器
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 单例bean名称和产生的工厂
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//spring早期版本存放bean名称和实例的容器,这是遗留字段
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
//单例对象名字的集合
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//判断单利对象是否要删除,如果true,就要删除上面三个单例对象的容器,默认fasle
private boolean singletonsCurrentlyInDestruction = false;
/** 按注册顺序排列的手动注册单例的名称列表. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
// 用于依赖列表和数组的可选的OrderComparator
private Comparator<Object> dependencyComparator;
//解析器用于检查bean定义是否为自动连接的候选
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
// 单例和非单例bean的映射,依赖于依赖类型
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
//依赖类型的名称
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
6、后置处理器容器
/** bean后置处理器BeanPostProcessors的实现类 */
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
/**指示是否已注册任何InstantiationWarebeanPostprocessors. */
private volatile boolean hasInstantiationAwareBeanPostProcessors;
/** 指示是否已注册任何DestructionAwareBeanPostProcessors. */
private volatile boolean hasDestructionAwareBeanPostProcessors;
7、父容器
// 父bean工厂
private BeanFactory parentBeanFactory;
8、类型解析
//设置EL表达式解析器(Bean初始化完成后填充属性时会用到),spring3增加了表达式语言的支持,默认可以使用#{bean.xxx}的形式来调用相关属性值
private BeanExpressionResolver beanExpressionResolver;
//spring属性类型转换
private ConversionService conversionService;
//设置属性注册解析器PropertyEditor 这个主要是对bean的属性等设置管理的一个工具
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
// 属性注册解析器容器
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
//类型转换器
private TypeConverter typeConverter;
//方法参数名的解析器策略
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
// 将字符串解析器应用于注释属性值
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();
有了上面的铺垫,我们开始从AnnotationConfigApplicationContext(Class>… annotatedClasses)方法中开始讲解
public interface BeanFactory {
//返回以给定名字注册的bean实例。如果没有找到指定的bean,将返回一个新建的实例
Object getBean(String name) throws BeansException;
<T> T getBean(String name, 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的提供程序,允许延迟按需检索实例,包括可用性和唯一性选项。
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
//容器中是否存在查找的bean
boolean containsBean(String name);
//是否singleton,如果bean没找到,则抛出NoSuchBeanDefinitionException异常
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//是否prototype,如果bean没找到,则抛出NoSuchBeanDefinitionException异常
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
//检查具有给定名称的bean是否与指定类型匹配。如果bean没找到,则抛出NoSuchBeanDefinitionException异常
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
//获取对应名字bean的类型。如果bean没找到,则抛出NoSuchBeanDefinitionException异常
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
//获取别名数组
String[] getAliases(String name);
}
1、beanFactory和factoryBean的区别
BeanFactory是接口,提供了IOC容器最基本的形式,给具体的IOC容器的实现提供了规范
FactoryBean也是接口,为IOC容器中Bean的注册提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式, 我们可以在getObject()方法中灵活配置。其实在Spring源码中有很多FactoryBean的实现类.
public interface FactoryBean<T> {
///返回的对象实例
@Nullable
T getObject() throws Exception;
//Bean的类型
@Nullable
Class<?> getObjectType();
//bean是否单例
default boolean isSingleton() {
return true;
}
}
区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
2、BeanFactory和ApplicationContext有什么区别?
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口
BeanFactory:是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
1、继承MessageSource,因此支持国际化。
2、统一的资源文件访问方式。
3、提供在监听器中注册bean的事件。
4、同时加载多个配置文件。
5、载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。