符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
BeanFactory的作用是什么,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
十年的天峨网站建设经验,针对设计、前端、开发、售后、文案、推广等六对一服务,响应快,48小时及时工作处理。全网整合营销推广的优势是能够根据用户设备显示端的尺寸不同,自动调整天峨建站的显示方式,使网站能够适用不同显示终端,在浏览器中调整网站的宽度,无论在任何一种浏览器上浏览网站,都能展现优雅布局与设计,从而大程度地提升浏览体验。创新互联建站从事“天峨网站设计”,“天峨网站推广”以来,每个客户项目都认真落实执行。
我们先来看看有哪些子类实现了它吧
其中ApplicationContext
这一块已在上篇文章有详细说明,而DefaultListableBeanFactory
这个底层实现类便理所当然的成为了我们此次探究的出发点,为了让 我们有个更好的观感,以下是纯粹的BeanFactory
UML图:
我们可以看到DefaultListableBeanFactory
实现的接口有:
SingletonBeanRegistry
: 定义了对单例缓存池相关的操作,如将bean注册到单例缓存池中
ConfigurableBeanFactory
: 可配置的BeanFactory
,定义了各种各样的配置能力,如bean的作用域,bean的classLoader,添加bean的后置处理器,设置bean的创建状态,销毁bean等等
AutowireCapableBeanFactory
: 能进行自动装配的BeanFactory
,这可能是我们最为熟悉的BeanFactory
,定义了自动装配的类型(byName/byType),createBean
, autowireBean
, 自动装配属性, populateBean, initializeBean, 对于与bean生命周期相关的方法都将在这里体现
ListableBeanFactory
: 对BeanFactory
的增强,定义了一系列根据beanType获取bean或者beanName的方法
ConfigurableListableBeanFactory
: 对ConfigurableBeanFactory
的增强,定义了忽略bean的类型、缓存bean定义、预实例化单例bean等方法
BeanDefinitionRegistry
: bean定义注册器,定义了与bean定义相关的方法
如果说以上的接口体现了DefaultListableBeanFactory
具备的功能,那么它所继承的一系列类就是这些功能的实现:
DefaultSingletonBeanRegistry
: 单例bean注册器,定义了三级缓存,其实就是三个Map属性
FactoryBeanRegistrySupport
: 提供对FactoryBean
的支持
AbstractBeanFactory
: 实现了一系列操作IOC容器的功能,但最终的createBean依旧交由子类AbstractAutowireCapableBeanFactory
完成
AbstractAutowireCapableBeanFactory
: 实现了创建bean的功能,所有与创建bean的相关的功能都在这里
DefaultListableBeanFactory
: 在以上父类的功能基础上实现了ConfigurableBeanFactory
和BeanDefinitionRegistry
接口,定义了一些存放Bean定义相关信息的Map
> 看到这里,想必对DefaultListableBeanFactory
已经有一个大致的了解了,那么问题来啦,我们应该怎么从容器中获取一个bean呢?是不是只要通过BeanDefinitionRegistry
注册一个bean定义,再通过AutowireCapableBeanFactory
去createBean就完成了呢?就像下面这样:
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class); beanFactory.registerBeanDefinition("wheel",beanDefinition); beanFactory.getBean("wheel", Wheel.class);
Bean
的元信息从何而来?我们现在已经知道DefaultListableBeanFactory
的大致功能了,我们发现当我们想要创建一个Bean
的时候,总是离不开一个名词:Bean定义,那么这个Bean定义究竟是什么呢?
BeanDefinition
其实是一个接口,并不是一个具体的类,我们也可以看一下它的UML图:
可以发现这里使用了模板方法的设计模式扩展了许多的子类,其中我们最常用的为RootBeanDefinition
,它主要包含的属性如下:
我们向容器中注册的Bean定义的信息大概就是如此,当BeanFactory
生产Bean
时,便可以通过beanClass
清楚的知道Bean
的类是什么,作用域是怎样,是否懒加载,init方法是什么等等等等
> 咦,如果一个最简单的bean,好像可以直接通过反射就搞定了耶~
具体结构已经清楚了,那我们来看一下注册过程吧
public static void main(String[] args) { //创建一个DefaultListableBeanFactory实例 DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //创建一个BeanDefinition RootBeanDefinition beanDefinition = new RootBeanDefinition(Wheel.class); //将BeanDefinition注册到容器中 beanFactory.registerBeanDefinition("wheel",beanDefinition); } public static class Wheel { }
public RootBeanDefinition(@Nullable Class beanClass) { //初始化父类 super(); //将beanClass赋值给this.BeanClass setBeanClass(beanClass); }
初始化父类
//将其中一部分属性赋予默认值 autowireCandidate = true; primary = false; protected AbstractBeanDefinition() { this(null, null); } protected AbstractBeanDefinition(@Nullable ConstructorArgumentValues cargs, @Nullable MutablePropertyValues pvs) { this.constructorArgumentValues = cargs; this.propertyValues = pvs; }
//除去校验逻辑,注册时只做了这两步操作 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName);
看到这里,大家伙可能会充满疑问?what? 就这样?没有填充属性的步骤吗?嘿嘿,BeanFactory
是一个纯粹的工厂,只负责生产Bean
,是没有装配(设计)BeanDefinition
的功能的,专业的事还是交给专业的人做,设计的事情还是交由ApplicationContext
完成的。
那在ApplicationContext
中是怎么完成一个BeanDefinition
的呢?还记得预启动将配置类注册到容器中时有这样一段代码吗?以下代码为AnnotatedBeanDefinitionReader#doRegisterBean
中的摘要部分:
void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name, @Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { //.......代码 //处理普通的bean定义注解,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); //......代码 }
而非配置的Bean
是通过在预启动时注册的配置类后置处理器ConfigurationClassPostProcessor#processConfigBeanDefinitions
中完成的,以下代码为ClassPathBeanDefinitionScanner#doScan
中的摘要部分,详细调用链将在后面的文章进行说明
//传入我们配置类的包路径 protected SetdoScan(String... basePackages) { Set beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { //寻找到所有标识了@Component注解的BeanDefinition Set candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { //....省略代码 if (candidate instanceof AbstractBeanDefinition) { //处理BeanDefinition postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //处理普通的bean定义注解,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //...省略代码 //将BeanDefinition注册到容器中 registerBeanDefinition(definitionHolder, this.registry); } }
处理BeanDefinition
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { //设置默认值 beanDefinition.applyDefaults(this.beanDefinitionDefaults); //这里默认为空 if (this.autowireCandidatePatterns != null) { beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName)); } }
设置默认值
public void applyDefaults(BeanDefinitionDefaults defaults) { //默认为null Boolean lazyInit = defaults.getLazyInit(); if (lazyInit != null) { setLazyInit(lazyInit); } //默认为0 setAutowireMode(defaults.getAutowireMode()); //默认为0 setDependencyCheck(defaults.getDependencyCheck()); //默认为null setInitMethodName(defaults.getInitMethodName()); setEnforceInitMethod(false); //默认为null setDestroyMethodName(defaults.getDestroyMethodName()); setEnforceDestroyMethod(false); }
处理普通的bean定义注解
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) { processCommonDefinitionAnnotations(abd, abd.getMetadata()); } static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) { //从元数据中取出该注解的属性列表,不为空说明有标识该注解 AnnotationAttributes lazy = attributesFor(metadata, Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } else if (abd.getMetadata() != metadata) { lazy = attributesFor(abd.getMetadata(), Lazy.class); if (lazy != null) { abd.setLazyInit(lazy.getBoolean("value")); } } //判断元数据中是否有该注解 if (metadata.isAnnotated(Primary.class.getName())) { abd.setPrimary(true); } AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class); if (dependsOn != null) { abd.setDependsOn(dependsOn.getStringArray("value")); } AnnotationAttributes role = attributesFor(metadata, Role.class); if (role != null) { abd.setRole(role.getNumber("value").intValue()); } AnnotationAttributes description = attributesFor(metadata, Description.class); if (description != null) { abd.setDescription(description.getString("value")); } }
attributesFor(metadata, Lazy.class)
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class annotationClass) { return attributesFor(metadata, annotationClass.getName()); } static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) { //metadata为beanClass的注解元数据,存放了该类所配置的所有注解 //annotationClassName为需要寻找的注解名称 return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false)); } default MapgetAnnotationAttributes(String annotationName, boolean classValuesAsString) { //遍历元数据中的所有注解 MergedAnnotation annotation = getAnnotations().get(annotationName, null, MergedAnnotationSelectors.firstDirectlyDeclared()); //不存在则返回null,否则返回一个map if (!annotation.isPresent()) { return null; } return annotation.asAnnotationAttributes(Adapt.values(classValuesAsString, true)); }
> 以上为扫描@Component注解类进行解析元数据填充属性的逻辑,在配置类中以@Bean方式注册的BeanDefinition填充属性过程在ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(configClasses)
BeanFactory
生产Bean
的过程是怎样的?现在,我们已经知道了一个BeanDefinition
的具体结构以及是如何产生并注册到BeanFactory
的,那么BeanFactory
又是如何使用它生产Bean
的呢?以下附上createBean
的粗略流程图,具体细节将放在IOC容器启动流程中详细说明
关于BeanFactory的作用是什么问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注创新互联行业资讯频道了解更多相关知识。