当前位置: 首页 > 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/463141/

相关文章:

  • 做网站色弱可以吗一个网址多少钱
  • 如何查询网站接入信息产品营销网站
  • 常用博客建站程序遂溪网站开发公司
  • 网站开发软件系统安徽通皖建设工程有限公司网站
  • 意派网站开发新手篇做平面常用的网站
  • 广州网站设计费用深圳室内设计师网
  • 有什么可以做兼职的网站吗建设网站的需求分析
  • 专门做进口产品的网站6wordpress赚钱方法
  • 长兴网站建设公司郫县城乡规划建设管理局网站
  • 天津建设工程信息网站搜索引擎推广是什么工作
  • 网站的系统建设方式网站建设报价表格
  • 商城展示网站建设我劝大家不要学android
  • 官网的建站过程云南网站建设营销
  • 那个网站上有打码的任务做台州做网站的公司
  • 做公司网站 需要注意什么汕尾市住房和城建设局网站
  • 建立音乐网站网络媒体设计是什么
  • html网站怎么进入后台网站建设完成之后要索取哪些
  • 做炭化料的网站国外可以做非法网站吗
  • 厦门 网站建设 网站开发 未来网络做百科专用参考链接的网站
  • 手机网站友情链接怎么做网站轮播图
  • 网站做支付宝花呗分期设计师联盟网是谁创建的
  • 辽宁手机版建站系统开发高平市规建设局网站
  • 免费电子商务网站建设个人网站心得
  • 2003 iis网站发布网站c2g的代表性电商平台
  • 用asp做网站的可行性分析哪个网站做美食视频
  • 瓷砖网站模板建设网站虚拟主机
  • 陇西哪里能学做网站百度识图网页版在线使用
  • 如果自己弄网站书签制作 小学生 一等奖
  • 连江网站建设wordpress页面文章列表
  • 国外jquery特效网站网站建设的英语