当前位置: 首页 > news >正文

网站建设工作报告简单游戏开发

网站建设工作报告,简单游戏开发,深圳建网页,汕头自助建站系统上文提到Spring在Bean扫描过程中#xff0c;会手动将5个Processor类注册到beanDefinitionMap中#xff0c;其中ConfigurationClassPostProcessor就是本文将要讲解的内容#xff0c;该类会在refresh()方法中通过调用invokeBeanFactoryPosstProcessors(beanFactory)被调用。 5… 上文提到Spring在Bean扫描过程中会手动将5个Processor类注册到beanDefinitionMap中其中ConfigurationClassPostProcessor就是本文将要讲解的内容该类会在refresh()方法中通过调用invokeBeanFactoryPosstProcessors(beanFactory)被调用。 5个Processor类列表如下 类名 是否BeanDefinitionRegistryPostProcessor 是否BeanFactoryPostProcessor 是否BeanPostProcessor ConfigurationClassPostProcessor 是 是 是 AutowiredAnnotationBeanPostProcessor 否 否 是 CommonAnnotationBeanPostProcessor 否 否 是 EventListenerMethodProcessor 否 是 否 DefaultEventListenerFactory 否 否 否 ConfigurationClassPostProcessor中两个核心方法将被调用其主要作用如下 方法名 作用 postProcessBeanDefinitionRegistry() 1Conditional注解条件解析 2被以下注解标注的类及内部类 Component、PropertySources、PropertySource、ComponentScans、ComponentScan、Import、ImportResource、Bean、接口中的Bean postProcessBeanFactory() 对full模式的配置类BeanDefinition进行CGLib增强把CGLib生成的子类型设置到beanDefinition中 postProcessBeanDefinitionRegistry()源码及注释如下 Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException(postProcessBeanDefinitionRegistry already called on this post-processor against registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException(postProcessBeanFactory already called on this post-processor against registry);}this.registriesPostProcessed.add(registryId);// 执行解析和扫描processConfigBeanDefinitions(registry);} 进入processConfigBeanDefinitions(registry)方法其主体逻辑流程图如下 其中标红步骤为两个关键步骤         1. 通过beanDefinition判断是否为配置类         Spring专门提供了一个工具类ConfigurationClassUtils来检查是否为配置类并标记full、lite模式逻辑如下         2. 解析配置类 doProcessConfigurationClass即为真正的对个注解的解析方法其逻辑流程图如下 具体的源码及详细注释如下 1. 主流程processConfigBeanDefinitions方法 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {// 候选配置类定义列表ListBeanDefinitionHolder configCandidates new ArrayList();// 获取容器中所有bean定义的名字String[] candidateNames registry.getBeanDefinitionNames();for (String beanName : candidateNames) {// 获取bean定义BeanDefinition beanDef registry.getBeanDefinition(beanName);// org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass// Bean Definition是否已经被标记为配置类(full、lite模式)if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) ! null) {if (logger.isDebugEnabled()) {logger.debug(Bean definition has already been processed as a configuration class: beanDef);}}// 查看bean是否是ConfigurationClass//被Configuration、Component、ComponentScan、Import、ImportResource、Bean标记else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {// 是配置类则加入到候选列表configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));}}// Return immediately if no Configuration classes were found// 如果为空即找不到被Configuration、Component、ComponentScan、Import、ImportResource、Bean标记的类则立即返回if (configCandidates.isEmpty()) {return;}// Sort by previously determined Order value, if applicable// 对需要处理的BeanDefinition排序值越小越靠前configCandidates.sort((bd1, bd2) - {int i1 ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());int i2 ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());return Integer.compare(i1, i2);});// Detect any custom bean name generation strategy supplied through the enclosing application context// 检查是否有自定义的beanName生成器SingletonBeanRegistry sbr null;if (registry instanceof SingletonBeanRegistry) {sbr (SingletonBeanRegistry) registry;if (!this.localBeanNameGeneratorSet) {//获取自定义的beanName生成器BeanNameGenerator generator (BeanNameGenerator) sbr.getSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);if (generator ! null) {// 如果spring有自定义的beanName生成器则重新赋值this.componentScanBeanNameGenerator generator;this.importBeanNameGenerator generator;}}}//如果环境对象为空则创建新的环境对象if (this.environment null) {this.environment new StandardEnvironment();}// 构造一个配置类解析器用来把bean定义的重要信息提取转化为ConfigurationClass// Parse each Configuration classConfigurationClassParser parser new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment,this.resourceLoader, this.componentScanBeanNameGenerator, registry);// 候选配置类定义列表查重SetBeanDefinitionHolder candidates new LinkedHashSet(configCandidates);// 存储已解析的配置类列表SetConfigurationClass alreadyParsed new HashSet(configCandidates.size());do {// 解析配置类parser.parse(candidates);// 配置类不能被申明为final(因为CGLIB的限制)除非它声明proxyBeanMethodsfalse// 在Configuration类中Bean方法的实例必须是可重写的以适应CGLIBparser.validate();// 获取解析器中解析出的配置类ConfigurationClass: parser.getConfigurationClasses()SetConfigurationClass configClasses new LinkedHashSet(parser.getConfigurationClasses());// 过滤掉已解析的配置类configClasses.removeAll(alreadyParsed);// 构造一个bean定义读取器// Read the model and create bean definitions based on its contentif (this.reader null) {this.reader new ConfigurationClassBeanDefinitionReader(registry, this.sourceExtractor, this.resourceLoader, this.environment,this.importBeanNameGenerator, parser.getImportRegistry());}// 读取ConfigurationClass获取衍生bean定义并注册到容器// 核心方法将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器this.reader.loadBeanDefinitions(configClasses);// 加入已解析配置类alreadyParsed.addAll(configClasses);// 清空候选配置类定义列表candidates.clear();// 如果容器中bean定义有新增if (registry.getBeanDefinitionCount() candidateNames.length) {// 查找出新增的配置类bean定义 startString[] newCandidateNames registry.getBeanDefinitionNames();SetString oldCandidateNames new HashSet(Arrays.asList(candidateNames));SetString alreadyParsedClasses new HashSet();for (ConfigurationClass configurationClass : alreadyParsed) {alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());}for (String candidateName : newCandidateNames) {if (!oldCandidateNames.contains(candidateName)) {BeanDefinition bd registry.getBeanDefinition(candidateName);if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) !alreadyParsedClasses.contains(bd.getBeanClassName())) {candidates.add(new BeanDefinitionHolder(bd, candidateName));}}}candidateNames newCandidateNames;}}while (!candidates.isEmpty());// Register the ImportRegistry as a bean in order to support ImportAware Configuration classes// 如果想要在Configuration类中使用ImportAware接口需要将ImportRegistry注册为bean。这样Configuration类就可以// 使用ImportRegistry来获取导入的类信息if (sbr ! null !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());}if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {// Clear cache in externally provided MetadataReaderFactory; this is a no-op// for a shared cache since itll be cleared by the ApplicationContext.// 如果MetadataReaderFactory是由外部提供的则需要清楚其缓存。但是如果MetadataReaderFactory是由ApplicationContext共享的则不需要进行清除// 因为ApplicationContext会自动清楚共享缓存((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();}} 2. 其中检查是否为配置类方法ConfigurationClassUtils.checkConfigurationClassCandidate //检查给定的BeanDefinition是否是一个配置类的候选者(或一个在配置/组件类中声明的嵌套组件类)//并对其进行相应的标记处理//被Configuration、Component、ComponentScan、Import、ImportResource、Bean标记public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {//获取bean定义信息中的class类名String className beanDef.getBeanClassName();//如果className为空或者bean定义信息中的factoryMethod不等于空那么直接返回if (className null || beanDef.getFactoryMethodName() ! null) {return false;}AnnotationMetadata metadata;//通过注解注入的BeanDefinition都是AnnotatedGenericBeanDefinition实现了AnnotatedBeanDefinition//Spring内部的BeanDefinition都是RootBeanDefiniton实现了AbstractBeanDefinition//此处主要用于判断是否是归属于AnnotatedBeanDefinitionif (beanDef instanceof AnnotatedBeanDefinition className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {// Can reuse the pre-parsed metadata from the given BeanDefinition...// 从当前bean的定义信息中获取元素metadata ((AnnotatedBeanDefinition) beanDef).getMetadata();}//判断是否是Spring中默认的BeanDefinitionelse if (beanDef instanceof AbstractBeanDefinition ((AbstractBeanDefinition) beanDef).hasBeanClass()) {// Check already loaded Class if present...// since we possibly cant even load the class file for this Class.//获取当前bean对象的Class对象Class? beanClass ((AbstractBeanDefinition) beanDef).getBeanClass();//如果class实例是下面4种类或者接口的子类父接口等任何一种情况直接返回if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||BeanPostProcessor.class.isAssignableFrom(beanClass) ||AopInfrastructureBean.class.isAssignableFrom(beanClass) ||EventListenerFactory.class.isAssignableFrom(beanClass)) {return false;}//为给定类创建新的AnnotationMetadatametadata AnnotationMetadata.introspect(beanClass);}//如果上述两种情况都不符合else {try {//获取className的MetadataReader实例MetadataReader metadataReader metadataReaderFactory.getMetadataReader(className);//读取底层类的完整注解元数据包括带注解方法的元数据metadata metadataReader.getAnnotationMetadata();}catch (IOException ex) {if (logger.isDebugEnabled()) {logger.debug(Could not find class file for introspecting configuration annotations: className, ex);}return false;}}// 获取Bean Definition的元数据被Configuration注解标注的属性字典值MapString, Object config metadata.getAnnotationAttributes(Configuration.class.getName());// 如果bean被Configuration注解标注并且proxyBeanMethods属性的值为true,则标注当前配置类为full即需要代理增强为一个代理类if (config ! null !Boolean.FALSE.equals(config.get(proxyBeanMethods))) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);}// 如果存在或者isConfigurationCandidate返回true,则标注当前配置类为lite,即不需要代理增强为一个普通类// 标注了Configuration注解且proxyBeanMethods属性的值为false则为lite模式// 没有标注Configuration注解但是标注了Component、ComponentScan、Import、ImportResource、Bean注解、则为lite模式else if (config ! null || isConfigurationCandidate(metadata)) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);}// 组件类不存在Configuration注解直接返回falseelse {return false;}// 获取配置类的排序顺序设置到组件定义属性中// Its a full or lite configuration candidate... Lets determine the order value, if any.//Bean Definition是一个标记为full/lite的候选项如果有order属性就设置order属性Integer order getOrder(metadata);if (order ! null) {//设置bean的order值beanDef.setAttribute(ORDER_ATTRIBUTE, order);}return true;} 3. 真正干活的方法doProessConfigurationClass // 通过读取源类的注释、成员和方法来构建完整的ConfigurationClass// 1.处理Component// 2.处理每个PropertySource// 3.处理每个ComponentScan// 4.处理每个Impoit// 5.处理每个ImportResource// 6.找配置类中Bean注解的方法(找出Class中存在Bean标注的方法加入到ConfigurationClass的beanMethods属性)// 7.找接口中Bean注解的方法// 8.存在父类则递归处理Nullableprotected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass, PredicateString filter)throws IOException {if (configClass.getMetadata().isAnnotated(Component.class.getName())) {// Recursively process any member (nested) classes first// 递归处理嵌套的成员类processMemberClasses(configClass, sourceClass, filter);}// Process any PropertySource annotations// 处理PropertySources和PropertySource注解for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);}else {logger.info(Ignoring PropertySource annotation on [ sourceClass.getMetadata().getClassName() ]. Reason: Environment must implement ConfigurableEnvironment);}}// Process any ComponentScan annotations// 处理ComponentScans和ComponentScan注解SetAnnotationAttributes componentScans AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);if (!componentScans.isEmpty() !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {for (AnnotationAttributes componentScan : componentScans) {// The config class is annotated with ComponentScan - perform the scan immediately// 配置类使用了注解ComponentScan - 立即执行扫描。SetBeanDefinitionHolder scannedBeanDefinitions this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());// Check the set of scanned definitions for any further config classes and parse recursively if neededfor (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand null) {bdCand holder.getBeanDefinition();}if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {parse(bdCand.getBeanClassName(), holder.getBeanName());}}}}// Process any Import annotations// 处理Import注解// getImports:递归获取Import导入的类processImports(configClass, sourceClass, getImports(sourceClass), filter, true);// Process any ImportResource annotations// 处理ImportResource注解// 读取locations, reader属性封装存放在importResources map集合中AnnotationAttributes importResource AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);if (importResource ! null) {String[] resources importResource.getStringArray(locations);Class? extends BeanDefinitionReader readerClass importResource.getClass(reader);for (String resource : resources) {String resolvedResource this.environment.resolveRequiredPlaceholders(resource);configClass.addImportedResource(resolvedResource, readerClass);}}// Process individual Bean methods// 处理Bean方法SetMethodMetadata beanMethods retrieveBeanMethodMetadata(sourceClass);for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}// Process default methods on interfaces// 处理接口的默认方法实现从jdk8开始接口中的方法可以有自己的默认实现因此如果这个接口的方法加了Bean注解也需要被解析processInterfaces(configClass, sourceClass);// Process superclass, if anyif (sourceClass.getMetadata().hasSuperClass()) {String superclass sourceClass.getMetadata().getSuperClassName();if (superclass ! null !superclass.startsWith(java) !this.knownSuperclasses.containsKey(superclass)) {this.knownSuperclasses.put(superclass, configClass);// Superclass found, return its annotation metadata and recursereturn sourceClass.getSuperClass();}}// No superclass - processing is completereturn null;}
http://www.pierceye.com/news/256516/

相关文章:

  • 网站建设首选公司wordpress需要mysql
  • 织梦 旅游网站模板深圳公司招牌制作
  • PHP网站开发如何建立vipwordpress页面伪静态
  • 主题公园旅游景区网站建设网站后台图片模板
  • 慈溪网站建设慈溪WordPress点击文章显示404
  • 网站建设与seo网站开发项目总结范文
  • 做竞彩网站代理犯法么建站公司 网站
  • 浙江建设证书查询seo服务公司深圳
  • 长沙协会网站设计专业服务医疗信息化软件公司排名
  • 北京网站制作一般多少钱黑色网站欣赏
  • 广州建设工程造价管理站wordpress获取文章title
  • 免费购物网站源码网站开发的论文引言
  • 商城网站开发需要哪些人员本机建的网站打开却很慢
  • 网站建设哪专业学会python做网站
  • vs怎么添加图片做网站地方门户网站管理系统
  • 三亚做网站的公司科技网站推荐
  • 电商网站运维怎么做自己做网站创业
  • seo有哪些网站集团公司网站 案例
  • 传媒大学附近网站建设公司天津市工程建设公众信息网官网
  • 关于网站建设与维护的参考文献家装设计费用多少钱一平方
  • 网站建设与管理专业概述网站建设报价费用是多少
  • asp医院网站源码破解版北京企业做网站报价
  • 个人做电商网站赚钱吗门业网站模板
  • 企业产品微网站收费吗wordpress移服务器改域名
  • 原创文章网站网站建设团队介绍
  • WordPress建站详细过程安康建设网站
  • 仿视频网站开发wordpress下载文件
  • 专业的个人网站建设哪家建筑施工企业专职安全生产管理员
  • 企业网站模板php全球网站排名前100
  • 1688网站可以做全屏吗有哪些网站是织梦做的