数据结构论坛

首页 » 分类 » 定义 » 十天8000字,我总结了这一篇Sprin
TUhjnbcbe - 2024/3/6 16:59:00

天下代码一大抄,抄来抄去有提高,看你会抄不会抄!

一、前言

Spring是java开发者,永远绕不开的结。Spring是非常值得开发者来学习的,以目前Spring在java领域的统治性地位,可以说学java就是在学Spring。但是作为新入门的开发人员,甚至说是有一定工作经验的同学,面对如此庞大的框架,都不一定是充分掌握了所有的知识点。因为大多数人的学习,都不是系统的学习,都是片面的。以经验为主。本系列专题的主要目的就是,一起系统的来学习一下Spring这个框架,以一个六年经验的老鸟的视角里,来重学Spring。通过直接阅读Spring的官方文档来获取一手知识。

因为内容较多,建议收藏学习。

二、BeanFactory工厂

2.1什么是Bean?

平时我们来创建对象,一般都是new。如果这个对象里有一个属性,那么就需要我来进行set,赋值。但是如果要有10个属性呢?你也要自己来赋值吗?那不累死个人嘛。Spring的解决方案就是,这么重的活,开发者不用关心了,都交给我来处理吧。那么Spring是如何来处理的呢?对,就是BeanFactory,Spring通过BeanFactory的方式帮实现对象的实例化。那么所有被Spring管理的对象,我们就可以理解成Bean对象。

凡是有属性和方法的对象都是Bean对象,凡是被Spring管理的Bean对象就是SpringBean对象。

2.2如何使用Bean工厂

方式一直接使用代码自动注入

ComponentpublicclassSpringIocTest{

AutowidprivateBeanFactorybeanFactory;}

方式二使用BeanFactoryAwa注入

ComponentpublicclassSpringIocTestimplementsBeanFactoryAwa{privateBeanFactorybeanFactory;

OverridepublicvoidsetBeanFactory(BeanFactorybeanFactory){this.beanFactory=beanFactory;}}

2.3BeanFactory的体系

在Spring中BeanFactory是一个非常重要的组件,要想搞清楚Spring,一定要先搞清楚BeanFactory的体系,这里我们详细来解释下BeanFactory的体系。

看这张图,密密麻麻的都是,但是我们不要担心,实际我们不用关心这么多。大部分人都是因为看到了这里,给劝退了,下面给大家精简一下。希望对你有所帮助。

我们只关心上面这张图就好了,但是看类还是比较多,为什么呢?因为Spring定义BeanFactory接口比较细,每个接口的维度都很细维度。但是我们能看到最底层的实现,是实现了所有接口的功能。下面我们以此来解释每个接口的功能。来窥探一下Spring中BeanFactory的体系。非常的全,建议大家可以收藏一下,没必要死记硬背。如果不理解的话,背下来也没有什么的用。

下面分享,希望对大家有点用。

2.3.1BeanFactory

最顶层的接口,提供了根据Bean名称获取Bean的最基础的能力。详细可以看下面的注释说明。接口没有任何实现,只是做定义。

publicinterfaceBeanFactory{//如果要获取FactoryBean,那么要的Bean的名称前加StringFACTORY_BEAN_PREFIX="";//根据名称获取实例,如果没有就抛异常,结果是Object类型ObjectgetBean(Stringname)throwsBeansException;//跟前者一样,不同是结果是泛型类型,会自动帮我们转换类型TTgetBean(Stringname,ClassTquidType)throwsBeansException;//允许指定显式构造函数参数,很少会用ObjectgetBean(Stringname,Object...args)throwsBeansException;//根据类型获取Bean实例,如果找到了多个类型,则会报错TTgetBean(ClassTquidType)throwsBeansException;//根据类型获取实例,并显式构造函数参数TTgetBean(ClassTquidType,Object...args)throwsBeansException;//根据类型获取Bean的生成对象,这里并不是直接获取了Bean的实例TObjectProviderTgetBeanProvider(ClassTquidType);//跟前者大同小异TObjectProviderTgetBeanProvider(ResolvableTypequidType);//判断是否保存这个名字的实例booleancontainsBean(Stringname);//判断是否单例booleanisSingleton(Stringname)throwsNoSuchBeanDefinitionException;//判断是否是原型模式booleanisPrototype(Stringname)throwsNoSuchBeanDefinitionException;//bean名称和类型是否匹配booleanisTypeMatch(Stringname,ResolvableTypetypeToMatch)throwsNoSuchBeanDefinitionException;//bean名称和类型是否匹配booleanisTypeMatch(Stringname,Class?typeToMatch)throwsNoSuchBeanDefinitionException;//获取名称的类型

NullableClass?getType(Stringname)throwsNoSuchBeanDefinitionException;//根据名称获取类型,FactoryBean比较特殊,allowFactoryBeanIn//it是说,是否也要算FactoryBean,一般情况用true

NullableClass?getType(Stringname,booleanallowFactoryBeanInit)throwsNoSuchBeanDefinitionException;//bean声明的别名,如果没有则为空数组String[]getAliases(Stringname);}

2.3.2HierarchicalBeanFactory

Hierarchical翻译:分层

HierarchicalBeanFactory的意思是具有层次关系,这个BeanFactory可以创建一个BeanFactory,那么是否可以根据这个BeanFactory知道是谁创建他的呢?这个接口就是干这个事情的。

publicinterfaceHierarchicalBeanFactoryextendsBeanFactory{//返回当前工厂的父工厂

NullableBeanFactorygetPantBeanFactory();//返回当工厂是否包含这个bean,不从父工厂中去获取booleancontainsLocalBean(Stringname);}

2.3.3ListableBeanFactory

一个接口可能会有多个实现,每个实现都是一个Bean。所以根据一个类型可能会获取多个Bean的实例。一个工厂会有很多的Bean,能不能一下获取工厂所有的Bean呢?

这个工厂名字定义的很有意思,Listable,List所以大多接口是返回集合。你不信,你看下面展示。

publicinterfaceListableBeanFactoryextendsBeanFactory{//是否包含BeanDefinition,BeanDefinition是bean实例化的基//本信息。booleancontainsBeanDefinition(StringbeanName);//获取BeanDefinition的数量intgetBeanDefinitionCount();//获取BeanDefinition的名称String[]getBeanDefinitionNames();//根据类型,获取这个类型的所有Bean的名称String[]getBeanNamesForType(ResolvableTypetype);//根据类型获取bean的名称,包含非单例的,允许初始化String[]getBeanNamesForType(ResolvableTypetype,booleanincludeNonSingletons,booleanallowEagerInit);//根据类型,获取这个类型的所有Bean的名称String[]getBeanNamesForType(

NullableClass?type);//根据类型获取bean的名称,包含非单例的,允许初始化String[]getBeanNamesForType(

NullableClass?type,booleanincludeNonSingletons,booleanallowEagerInit);//根据类型获取Bean的字典,key是名称value是实例TMapString,TgetBeansOfType(

NullableClassTtype)throwsBeansException;//根据类型获取Bean的字典(包含非单例),key是名称value是实例TMapString,TgetBeansOfType(

NullableClassTtype,booleanincludeNonSingletons,booleanallowEagerInit)throwsBeansException;//获取被当前注解修饰的Bean的名称,只获取名称不实例化,支持注解派//生的方式String[]getBeanNamesForAnnotation(Class?extendsAnnotationannotationType);//获取被该注解修饰的bean,key是名称,value是实例。MapString,ObjectgetBeansWithAnnotation(Class?extendsAnnotationannotationType)throwsBeansException;//获取当前名称Bean的,当前注解的信息

NullableAextendsAnnotationAfindAnnotationOnBean(StringbeanName,ClassAannotationType)throwsNoSuchBeanDefinitionException;}

2.3.4ConfigurableBeanFactory

这个工厂,是最容易看出他的用途的,名字一个看就是跟配置相关的。

publicinterfaceConfigurableBeanFactoryextendsHierarchicalBeanFactory,SingletonBeanRegistry{//单例:一个容器只都存在实例StringSCOPE_SINGLETON="singleton";//原型:每次getBean一次生成一个实例StringSCOPE_PROTOTYPE="prototype";//设置他的父工厂voidsetPantBeanFactory(BeanFactorypantBeanFactory)throwsIllegalStateException;//设置类加载器以用于加载bean类。默认是线程上下文类加载器。voidsetBeanClassLoader(

NullableClassLoaderbeanClassLoader);//返回此工厂的类加载器以加载bean类

NullableClassLoadergetBeanClassLoader();//指定用于类型匹配目的的临时ClassLoader。默认为无voidsetTempClassLoader(

NullableClassLoadertempClassLoader);//获取临时的类加载器

NullableClassLoadergetTempClassLoader();//设置是否缓存bean元数据,例如给定的bean定义(以合并方式)和解析的bean类。默认开启。voidsetCacheBeanMetadata(booleancacheBeanMetadata);//返回是否缓存bean元数据booleanisCacheBeanMetadata();//bean定义值中的表达式指定解析策略。//默认是StandardBeanExpssionResolver。voidsetBeanExpssionResolver(

NullableBeanExpssionResolversolver);//获取解析类型StandardBeanExpssionResolver

NullableBeanExpssionResolvergetBeanExpssionResolver();//设置转换层统一的API,后面有专门章节说这个体系。voidsetConversionService(

NullableConversionServiceconversionService);//获取转换API

NullableConversionServicegetConversionService();//给工厂添加一个属性设置的注册器,实际用的不多,但是有必要去了解,后面也会介绍voidaddPropertyEditorRegistrar(PropertyEditorRegistrargistrar);//为给定类型的所有属性注册给定的自定义属性编辑器。在工厂配置期间调用。voidgisterCustomEditor(Class?quidType,Class?extendsPropertyEditorpropertyEditorClass);//BeanFactory中注册的自定义编辑器初始化给定的PropertyEditorRegistryvoidcopyRegistedEditorsTo(PropertyEditorRegistrygistry);//设置类型转换器voidsetTypeConverter(TypeConvertertypeConverter);//获取类型转换器TypeConvertergetTypeConverter();//添加字符串解析器。voidaddEmbeddedValueResolver(StringValueResolvervalueResolver);//是否有字符串解析器booleanhasEmbeddedValueResolver();//解析数据

NullableStringsolveEmbeddedValue(Stringvalue);//添加一个新的BeanPostProcessor,它将应用于此工厂创建的bean。在工厂配置期间调用。//非系统定义的处理器,都可以使用Order进行排序//这是一个非常重要的Bean处理器voidaddBeanPostProcessor(BeanPostProcessorbeanPostProcessor);//处理器的个人intgetBeanPostProcessorCount();//注册由给定Scope实现支持的给定范围//这里稍微解释下什么是Scope,就比如Session内有效或者是Request内有效voidgisterScope(StringscopeName,Scopescope);//返回所有当前注册范围的名称,不会公开诸如“singleton”和“prototype”之类的内置作用域String[]getRegistedScopeNames();//获取域的域对象

NullableScopegetRegistedScope(StringscopeName);//提供与该工厂相关的安全访问控制上下文。AccessControlContextgetAccessControlContext();//拷贝当Bean工厂的配置voidcopyConfigurationFrom(ConfigurableBeanFactoryotherFactory);//给bean注册一个别名voidgisterAlias(StringbeanName,Stringalias)throwsBeanDefinitionStoException;//解析在此工厂中注册的所有别名目标名称和别名,并将给定的StringValueResolver应用于它们。voidsolveAliases(StringValueResolvervalueResolver);//返回给定bean名称的合并BeanDefinition,如有必要,将子bean定义与其父合并。BeanDefinitiongetMergedBeanDefinition(StringbeanName)throwsNoSuchBeanDefinitionException;//是否是FactoryBeanbooleanisFactoryBean(Stringname)throwsNoSuchBeanDefinitionException;//设置当前Bean正在创建中。仅供容器内部会使用。voidsetCurntlyInCation(StringbeanName,booleaninCation);//当前Bean是否创建中booleanisCurntlyInCation(StringbeanName);//为给定的bean注册一个依赖beanvoidgisterDependentBean(StringbeanName,StringdependentBeanName);//返回依赖于指定bean的所有bean的名称String[]getDependentBeans(StringbeanName);//获取当前Bean依赖的BeanString[]getDependenciesForBean(StringbeanName);//销毁beanvoiddestroyBean(StringbeanName,ObjectbeanInstance);//销毁当前目标作用域中的指定作用域bean(如果有)voiddestroyScopedBean(StringbeanName);//销毁单例voiddestroySingletons();}

2.3.5AutowiCapableBeanFactory

Autowi是不是看着很熟,提供自动注入的方法。

publicinterfaceAutowiCapableBeanFactoryextendsBeanFactory{//不需要自动装配intAUTOWIRE_NO=0;//表示按名称自动装配bean属性的常量intAUTOWIRE_BY_NAME=1;//按照类型来自动装配intAUTOWIRE_BY_TYPE=2;//指示自动装配可以满足的最贪婪构造函数的常量intAUTOWIRE_CONSTRUCTOR=3;//

DepcatedintAUTOWIRE_AUTODETECT=4;//5.1才有的。初始化现有bean实例时的“原始实例”约定的后缀:附加到完全限定的bean类名,例如“
1
查看完整版本: 十天8000字,我总结了这一篇Sprin