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

建网站做哪方面中国建设银行个人登陆网站

建网站做哪方面,中国建设银行个人登陆网站,陈江网站建设,网站开发都需要哪些图Spring源码核心篇整体栏目 内容链接地址【一】Spring的bean的生命周期https://zhenghuisheng.blog.csdn.net/article/details/143441012【二】深入理解spring的依赖注入和属性填充https://zhenghuisheng.blog.csdn.net/article/details/143854482【三】精通spring的aop的底层原…Spring源码核心篇整体栏目 内容链接地址【一】Spring的bean的生命周期https://zhenghuisheng.blog.csdn.net/article/details/143441012【二】深入理解spring的依赖注入和属性填充https://zhenghuisheng.blog.csdn.net/article/details/143854482【三】精通spring的aop的底层原理和源码实现https://zhenghuisheng.blog.csdn.net/article/details/144012934【四】spring中refresh刷新机制的流程和实现https://zhenghuisheng.blog.csdn.net/article/details/144118337【五】spring中循环依赖的解决和底层实现https://zhenghuisheng.blog.csdn.net/article/details/144132213【六】spring中事务的底层实现与执行流程https://zhenghuisheng.blog.csdn.net/article/details/144178500【七】spring中事物传播机制的流程和原理https://zhenghuisheng.blog.csdn.net/article/details/144178500【八】spring中配置类底层原理和源码实现https://zhenghuisheng.blog.csdn.net/article/details/148657333 spring配置类实现原理 一. 深入理解spring配置类实现原理1配置类方法入口checkConfigurationClassCandidate2解析配置类doProcessConfigurationClass2.1. PropertySource 解析2.2. ComponentScan 解析2.3. Import 解析2.4. ImportResource 解析2.5. Bean 解析2.6. 父类解析 3注册配置类的beanDefinition3.1. Import注解生成BeanDefinition3.2. Bean注解生成BeanDefinition3.3. ImportResources注解生成BeanDefinition 如需转载请附上链接:https://blog.csdn.net/zhenghuishengq/article/details/148657333 一. 深入理解spring配置类实现原理 在spring中内部存在一些配置类配置注解在我们使用这些注解的时候可以手动的将一些配置类加载到spring容器中类似与比较常规的 Configuration 注解等除了这个注解之外spring内部也提供了多个这种注解接下来从spring源码中来分析这些配置类以及配置注解 在spring源码中会解析配置类校验是否配置类的入口如下通过下面这个方法来判断该 ConfigurationClassUtils.checkConfigurationClassCandidate(...)1配置类方法入口checkConfigurationClassCandidate 其方法详情如下主要是通过获取类上面的注解然后通过注解来判断该类是不是配置类 首先会判断这个类上面是不是加了这个 Configuration 注解 AnnotationMetadata metadata; // 校验是不是加了 Configuration 注解 if (isFullConfigurationCandidate(metadata)) {//如果加了那么给这个注解上面加一个标记beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {return metadata.isAnnotated(Configuration.class.getName()); }接下来根据源码继续往下走上面是一个full重的配置类接下来会判断一些lite配置类即一些比较轻的配置类 else if (isLiteConfigurationCandidate(metadata)) {beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); }这个lite轻的配置类的具体实现如下首先会判断要加载的类上面的注解包不包括在 candidateIndicators 集合列表中 这个set集合中包括的主要注解如下Component、ComponentScan、Import、ImportResource 这四个除了这几个之外下面还会判断内部是否有 Bean 注解 private static final SetString candidateIndicators new HashSet(8); static {candidateIndicators.add(Component.class.getName());candidateIndicators.add(ComponentScan.class.getName());candidateIndicators.add(Import.class.getName());candidateIndicators.add(ImportResource.class.getName()); }也就是说只要类上面有 以下注解那么spring就会将这些类扫描并解析成一个配置类 ConfigurationBeanComponentComponentScanImportImportResource 2解析配置类doProcessConfigurationClass 在refresh方法中会有一个 invokeBeanFactoryPostProcessors 方法在内部就会调用到这个 doProcessConfigurationClass 真正的去解析这个配置类的方法。接下来直接看源码看看内部到底是如何解析的。 2.1. PropertySource 解析 首先第一步是解析带有这个 PropertySource 注解的实体类这个注解就是用于处理 Properties 配置文件的将配置文件中的内容加载到spring容器内部 for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class,org.springframework.context.annotation.PropertySource.class)) {if (this.environment instanceof ConfigurableEnvironment) {processPropertySource(propertySource);} }2.2. ComponentScan 解析 接下来解析的是这个 ComponentScan 注解ComponentScan说白了就是对 Component注解的扫描判断类上面是否有这个 Component注解在前面讲解bean的生命周期的时候重点的讲解过。 for (AnnotationAttributes componentScan : componentScans) {//把我们扫描出来的类变为bean定义的集合 真正的解析SetBeanDefinitionHolder scannedBeanDefinitions this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());//循环处理我们包扫描出来的bean定义for (BeanDefinitionHolder holder : scannedBeanDefinitions) {BeanDefinition bdCand holder.getBeanDefinition().getOriginatingBeanDefinition();if (bdCand null) {bdCand holder.getBeanDefinition();}//判断当前扫描出来的bean定义是不是一个配置类,若是的话 直接进行递归解析if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {//递归解析 因为Component算是lite配置类parse(bdCand.getBeanClassName(), holder.getBeanName());}} }首先会将这些扫描到的类解析成一个 BeanDefinition判断是否存在includeFilters中excludeFilters中然后判断是否Lazy DependsOn等注解最后将这些属性全部注册到beanDefinition中返回 this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName())最后又会判断这个类属不属于配置类属于的话再次递归解析判断这个类可不可能存在父类也需要解析成配置类等直到返回null跳出递归 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {//递归解析 因为Component算是lite配置类parse(bdCand.getBeanClassName(), holder.getBeanName()); }2.3. Import 解析 接下来就是处理Import的注解这个部分的解析相对绕一些。首先会调用这个 getImports 方法获取全部带有Import的类 processImports(configClass, sourceClass, getImports(sourceClass), true);然后遍历这些获取的Import实例里面会有三个分支校验这些加了Import的类上面是否是单纯的加了这个注解还是同时实现了别的接口要对相关实现的接口做不同的判断 for (SourceClass candidate : importCandidates) {... }1首先是先看只有单纯加了Import的配置类spring会直接将这种配置类进行解析注册 else {// 当做配置类再解析注意这里会标记importedBy 表示这是Import的配置的类// 再执行之前的processConfigurationClass()方法 this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());processConfigurationClass(candidate.asConfigClass(configClass)); } 2随后是判断这个加了Import注解的类同时实现了 ImportSelector 接口如果是的话那么会先实例化一个 ImportSelector 组件然后通过递归的方式将一个ImportSelector组件解析成上面多个 Import 组件最后又调用这个 processImports 方法将解析成多个的import组件走上面的这个else逻辑 if (candidate.isAssignable(ImportSelector.class)) {// Candidate class is an ImportSelector - delegate to it to determine importsClass? candidateClass candidate.loadClass();//实例化我们的SelectImport组件ImportSelector selector BeanUtils.instantiateClass(candidateClass, ImportSelector.class);//调用相关的aware方法ParserStrategyUtils.invokeAwareMethods(selector, this.environment, this.resourceLoader, this.registry);//判断是不是延时的DeferredImportSelectors是这个类型 不进行处理if (this.deferredImportSelectors ! null selector instanceof DeferredImportSelector) {this.deferredImportSelectors.add(new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));}else {//不是延时的//调用selector的selectImportsString[] importClassNames selector.selectImports(currentSourceClass.getMetadata());// 所以递归解析-- 直到成普通组件CollectionSourceClass importSourceClasses asSourceClasses(importClassNames);processImports(configClass, currentSourceClass, importSourceClasses, false);} }3最后再看这个加了Import注解同时也实现了 ImportBeanDefinitionRegistrar 接口的方法他和上面这个实现 ImportSelector 的方式不同不会解析转成多个Import而是作为一个属性加入到 ConfigurationClass配置类中 else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {Class? candidateClass candidate.loadClass();//实例话我们的ImportBeanDefinitionRegistrar对象ImportBeanDefinitionRegistrar registrar BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);ParserStrategyUtils.invokeAwareMethods(registrar, this.environment, this.resourceLoader, this.registry);//保存我们的ImportBeanDefinitionRegistrar对象 currentSourceClass所在配置类configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); }2.4. ImportResource 解析 接下来就是处理这个 ImportResource 注解其主要实现如下 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);} }其核心就在于下面这句用于获取本地的一些环境变量或者一些属性比如获取一些 xml 文件中的一些配置属性等然后将内容读取到配置文件 String resolvedResource this.environment.resolveRequiredPlaceholders(resource);最后也是作为一个属性加入到 ConfigurationClass 配置文件中和上面实现这个 ImportBeanDefinitionRegistrar 接口的一样目前只是将这些属性加入到配置文件中还有生成具体的beanDefinition configClass.addImportedResource(resolvedResource, readerClass);2.5. Bean 解析 接下来就是接下这个 Bean注解这里也比较简单就是在类中获取全部带有 Bean的注解然后去遍历这些元数据然后将这些打包成一个 BeanMethod实体加入到ConfigurationClass配置文件中 // 获取全部带有 Bean的方法 SetMethodMetadata beanMethods retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) {configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); }除了在类中获取 Bean 注解之外他还有一个在接口中获取该注解的解析。比如有的接口的default方法中加了这个注解进行注入但其实现和在类中找一致也是将这些打包成BeanMethod实体类加入到配置文件中 processInterfaces(configClass, sourceClass);private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {for (SourceClass ifc : sourceClass.getInterfaces()) {SetMethodMetadata beanMethods retrieveBeanMethodMetadata(ifc);for (MethodMetadata methodMetadata : beanMethods) {if (!methodMetadata.isAbstract()) {// A default method or other concrete method on a Java 8 interface...configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));}}processInterfaces(configClass, ifc);} }2.6. 父类解析 最后就剩一个父类解析因为很多地方涉及到递归解析判断父类是否也是一个配置类因此需要在此处进行处理 递归直到没有父类需要解析那么就会返回一个null前面的while需要通过这个返回的null跳出递归可以参考源码实现。 // 处理配置类的父类的 循环再解析 if (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();} } // 没有父类解析完成 return null;3注册配置类的beanDefinition 上面PropertySource 、ComponentScan 、Import 都注册成了对应的beanDefinition而Bean、ImportResource 注解目前只是封装成了实体加载到了配置类中还没有进行注册到对应beanDefinition中那么继续看源码底层是如何将后面加到配置类的几个注册成bean定义的 还是得回到 processConfigBeanDefinitions 中查看这个Bean和实现了这个 ImportBeanDefinitionRegistrar 的 Import方法时如何解析成BeanDefinition的这块内容在前面讲解bean的生命周期的时候详细的讲过这个也是前面的一个流程 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {// 此处才把Bean的方法和Import 注册到BeanDefinitionMap中this.reader.loadBeanDefinitions(configClasses); }接下来直接查看这个 loadBeanDefinitions 方法里面也没做特别的事情就是一个循环 public void loadBeanDefinitions(SetConfigurationClass configurationModel) {TrackedConditionEvaluator trackedConditionEvaluator new TrackedConditionEvaluator();//注册我们的配置类到容器中for (ConfigurationClass configClass : configurationModel) {loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);} }接下来重点查看这个 loadBeanDefinitionsForConfigurationClass 方法在这个方法中对Import、Bean、ImportResources、ImportBeanDefinition 注解进行解析然后生成对应的beanDefinition 3.1. Import注解生成BeanDefinition 首先会判断这个配置类是不是导入进来的 if (configClass.isImported()) {registerBeanDefinitionForImportedConfigurationClass(configClass); }如果这个类是通过Import导入进来的那么会调用这个 registerBeanDefinitionForImportedConfigurationClass 方法来将这个类注册成 BeanDefinition会设置一些元数据信息bean定义作用域等最后通过注册的方式将这个实体类注册成一个BeanDefinition 3.2. Bean注解生成BeanDefinition 随后会判断这个配置类上面是不是通过Bean的方式注入进来的如果是通过Bean方式注入进来的前面已经将Bean的配置类包装成了 BeanMethod 实体类因此只需要遍历这个配置类中的 BeanMethods实体类集合即可 //是不是通过我们的bean导入进来的组件 for (BeanMethod beanMethod : configClass.getBeanMethods()) {loadBeanDefinitionsForBeanMethod(beanMethod); }这个解析会相对复杂点里面设计多重校验最后注册成BeanDefinition private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {//设计大量的校验...// 最后注册成BeanDefinition中this.registry.registerBeanDefinition(beanName, beanDefToRegister); }3.3. ImportResources注解生成BeanDefinition 随后判断是不是importResources注解注入进来的 private void loadBeanDefinitionsFromImportedResources(){... }主要是加载一些grovvy配置文件或者xml文件然后将这些配置文件设置到环境变量中 最后将这个配置文件通过reader读取的方式加载到配置文件中 reader.loadBeanDefinitions(resource);
http://www.w-s-a.com/news/429987/

相关文章:

  • 各电商网站的特点网站制作2007
  • 用html做一号店网站怎么做公众号注册平台官网
  • 做盈利网站怎么备案vs做网站如何调试
  • 嘉兴做营销型网站廊坊做网站外包
  • 双语网站模板常州做网站的公司
  • 广州市车管所网站建设全国做网站公司前十名
  • 太原手手工网站建设公司视频直播服务
  • 雷达图 做图网站wordpress首页怎么美化
  • 四川做网站设计公司价格vip解析网站怎么做的
  • 网站建设流程域名申请做化工的 有那些网站
  • 软件开发设计流程图seo搜索引擎官网
  • 外国小孩和大人做网站东富龙科技股份有限公司
  • 上线倒计时单页网站模板做网站的资金来源
  • 泸州市建设厅网站中小企业网络需求分析
  • asp网站版权做网页价格
  • 长春网站建设路关键词优化公司哪家好
  • 河南省建设银行网站年报天津设计师网站
  • 沙洋网站定制如果自己建立网站
  • 凡科网站怎么做建站关键字搜索网站怎么做
  • 小说网站建站程序企业邮箱地址
  • 福州市住房和城乡建设网站网站开发方案论文
  • 在线教育网站开发网站推广常用方法包括
  • 东莞高端品牌网站建设软件开发模型及特点
  • 个人网站的设计与实现的主要内容网站开发公司架构
  • 浏览器收录网站什么是新媒体营销
  • 上海营销网站建设公司下面哪个不是网页制作工具
  • 有哪些网站可以做设计比赛苏州设计公司排名前十
  • 公益网站建设需求车陂手机网站开发
  • 高端网站建设专业营销团队宁德网站建设51yunsou
  • 网站如何做cdn购物网站建设app开发