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

安徽外贸网站google建站网站服务器报价

安徽外贸网站google建站,网站服务器报价,静态网站开发网站,预约做家庭清洁的网站文章目录 前言一、scanCandidateComponents1.1 isCandidateComponent1.1.1、排除/包含过滤器1.1.2、条件装配1.1.3、重载一1.1.4、重载二1.1.5、补充#xff1a;Lookup注解 总结 前言 原生的Spring在构造ApplicationContext时#xff0c;会调用refresh方法。其中就包含了扫描… 文章目录 前言一、scanCandidateComponents1.1 isCandidateComponent1.1.1、排除/包含过滤器1.1.2、条件装配1.1.3、重载一1.1.4、重载二1.1.5、补充Lookup注解 总结 前言 原生的Spring在构造ApplicationContext时会调用refresh方法。其中就包含了扫描所有包含Component及其子注解的类注解模式或解析xml配置文件xml模式将其注册为BeanDefinition的逻辑。 一、scanCandidateComponents scanCandidateComponents是扫描指定路径下的类并且将符合要求的类进行解析注册成BeanDefinition的逻辑。   在该方法中 将传入的类路径进行格式转换。获取指定类路径下的所有.class文件。通过MetadataReader 解析.class的元数据信息。 获得类的元数据信息判断类上是否有相关注解的方式有两种第一是通过JVM的类加载第二是MetadataReader 。为什么Spring选择的是后者因为JVM的类是懒加载的如果在Spring启动时就将所有目标路径下的类全部通过JVM加载那么就违背了JVM类加载的机制。并且如果目标路径下的类很多对于性能也有一定的损失。而MetadataReader 使用的是ASM技术 最终。得到的是BeanDefinition对象而不是在JVM中加载.class文件。 /*** 参数需要扫描的类路径 例com.itbaima* 返回值BeanDefinition的集合**/private SetBeanDefinition scanCandidateComponents(String basePackage) {SetBeanDefinition candidates new LinkedHashSet();try {//将参数中的类路径进行转换 com.itbaima-classpath*:com/itbaima/**/*.classString packageSearchPath ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX resolveBasePackage(basePackage) / this.resourcePattern;//得到指定类路径下的所有资源文件类的.class文件 //例:file [D:\Idea_workspace\2024\springplus\target\classes\com\itbaima\AppConfig.class]Resource[] resources getResourcePatternResolver().getResources(packageSearchPath);boolean traceEnabled logger.isTraceEnabled();boolean debugEnabled logger.isDebugEnabled();//遍历这些资源文件for (Resource resource : resources) {if (traceEnabled) {logger.trace(Scanning resource);}try {//通过MetadataReader 对某个.class文件的元数据进行解析MetadataReader metadataReader getMetadataReaderFactory().getMetadataReader(resource);//1.1 isCandidateComponentif (isCandidateComponent(metadataReader)) {//创建BeanDefinitionScannedGenericBeanDefinition sbd new ScannedGenericBeanDefinition(metadataReader);//设置BeanDefinition的source属性 file [D:\Idea_workspace\2024\springplus\target\classes\com\itbaima\AppConfig.class]sbd.setSource(resource);//再次进行判断对应的类是不是接口或抽象类(和上面的isCandidateComponent是重载的方法)if (isCandidateComponent(sbd)) {if (debugEnabled) {logger.debug(Identified candidate component class: resource);}//将该BeanDefinition放入集合中candidates.add(sbd);}else {if (debugEnabled) {logger.debug(Ignored because not a concrete top-level class: resource);}}}else {if (traceEnabled) {logger.trace(Ignored because not matching any filter: resource);}}}catch (FileNotFoundException ex) {if (traceEnabled) {logger.trace(Ignored non-readable resource : ex.getMessage());}}catch (Throwable ex) {throw new BeanDefinitionStoreException(Failed to read candidate component class: resource, ex);}}}catch (IOException ex) {throw new BeanDefinitionStoreException(I/O failure during classpath scanning, ex);}return candidates;}1.1 isCandidateComponent 在ClassPathScanningCandidateComponentProvider中isCandidateComponent有两个第一个主要是用于判断类元信息中是否需要排除/包含注解 ExcludeFilter表示排除过滤器IncludeFilter表示包含过滤器 1.1.1、排除/包含过滤器 ExcludeFilter的作用被排除在外的类即使类上加入了Component及其子注解也不会被扫描到 Component public class OrderService { }Component public class UserService { }ComponentScan(value org.ragdollcat,excludeFilters {ComponentScan.Filter(type FilterType.ASSIGNABLE_TYPE,classes UserService.class)}) public class AppConfig { }public class Demo1 {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);System.out.println(context.getBean(orderService));System.out.println(context.getBean(userService));} } IncludeFilter的作用被包含的类即使类上没有加入Component及其子注解也会被扫描到 ComponentScan(value org.ragdollcat,includeFilters {ComponentScan.Filter(type FilterType.ASSIGNABLE_TYPE,classes UserService.class)}) public class AppConfig { }public class UserService { } 1.1.2、条件装配 这里还有一个条件装配的概念我们可以自定义一个类实现Condition 接口重写matches方法自定义匹配的逻辑 Component public class MyConditional implements Condition {public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return false;} }并且在需要条件装配的类上加入Conditional注解 Component Conditional(MyConditional.class) public class UserService { } 1.1.3、重载一 在isCandidateComponent方法中 判断判断类元信息中是否需要排除/包含注解。如果类元信息中需要包含某个注解能匹配的上如果还有Conditional注解则需要再次判断是否符合条件。 /*** 判断类元信息中是否需要排除/包含注解* 参数类元信息*/protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {//如果当前元数据中的注解 有符合需要排除的注解 则返回falsefor (TypeFilter tf : this.excludeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return false;}}//如果当前元数据中的注解 有符合包含的注解 则再次进入判断for (TypeFilter tf : this.includeFilters) {if (tf.match(metadataReader, getMetadataReaderFactory())) {return isConditionMatch(metadataReader);}}return false;}/*** 主要用于判断条件装配**/private boolean isConditionMatch(MetadataReader metadataReader) {if (this.conditionEvaluator null) {this.conditionEvaluator new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);}return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());}public boolean shouldSkip(Nullable AnnotatedTypeMetadata metadata, Nullable ConfigurationPhase phase) {//元数据为空 或者类上没有加Conditional注解 无需判断 直接返回falseif (metadata null || !metadata.isAnnotated(Conditional.class.getName())) {return false;}if (phase null) {if (metadata instanceof AnnotationMetadata ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);}return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);}ListCondition conditions new ArrayList();//得到所有实现了Condition接口的类for (String[] conditionClasses : getConditionClasses(metadata)) {for (String conditionClass : conditionClasses) {//转换为Condition 对象Condition condition getCondition(conditionClass, this.context.getClassLoader());//加入到集合中conditions.add(condition);}}AnnotationAwareOrderComparator.sort(conditions);for (Condition condition : conditions) {ConfigurationPhase requiredPhase null;if (condition instanceof ConfigurationCondition) {requiredPhase ((ConfigurationCondition) condition).getConfigurationPhase();}//关键点调用自定义实现了Condition接口的类 的match方法 查看返回结果if ((requiredPhase null || requiredPhase phase) !condition.matches(this.context, metadata)) {//如果自定义实现了Condition接口的类 的match方法 返回的是false 则 这里返回的true 表示需要跳过加上了Condition注解的类的扫描return true;}}return false;}在进行匹配时调用的核心方法 Overrideprotected boolean matchSelf(MetadataReader metadataReader) {//首先获取类元数据上的注解信息AnnotationMetadata metadata metadataReader.getAnnotationMetadata();//返回判断的结果//1、类上有Component及其子注解 或 2、considerMetaAnnotations 为true 并且类上有Component及其子注解return metadata.hasAnnotation(this.annotationType.getName()) ||(this.considerMetaAnnotations metadata.hasMetaAnnotation(this.annotationType.getName()));}1.1.4、重载二 第二个isCandidateComponent方法主要是判断当前类是否是接口或者抽象类有一种特殊情况即该类是抽象类但是有Lookup注解也会被装配。 protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {AnnotationMetadata metadata beanDefinition.getMetadata();return (metadata.isIndependent() (metadata.isConcrete() ||(metadata.isAbstract() metadata.hasAnnotatedMethods(Lookup.class.getName()))));}default boolean isConcrete() {//如果是接口或者抽象类 则返回falsereturn !(isInterface() || isAbstract());}1.1.5、补充Lookup注解 如果某个单例bean中有个属性是多例的在初始化单例后每次获取到的属性的地址值都是一样的 Component Scope(prototype) public class User { }Component public class OrderService {Autowiredprivate User user;public void test(){System.out.println(user);}// Lookup(user) // public User m1(){ // return null; // } }public class Demo1 {public static void main(String[] args) {AnnotationConfigApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class);OrderService orderService (OrderService) context.getBean(orderService);orderService.test();orderService.test();orderService.test();}} 如果要每次获取不同的属性可以使用Lookup注解实现 Component public class OrderService {Autowiredprivate User user;public void test(){System.out.println(m1());}Lookup(user)public User m1(){return null;} }总结 在Scan方法中主要做了 将传入参数的路径进行转换转换为classpath的格式。获取路径下的所有资源文件.class。通过MetadataReader 解析.class的元数据信息。判断被扫描到的类上是否存在Component及其子注解并且有无需要排除某个类的情况。还需要判断类上是否加入了Conditional注解。如果有调用Conditional注解value中的类的.matches方法判断是否需要跳过该类。将被扫描的类包装成BeanDefinition对象。再次判断被扫描的类是否是接口/抽象类。如果是则不将其创建为BeanDefinition。有加入了Lookup的抽象类的特殊情况。将BeanDefinition对象加入集合。
http://www.w-s-a.com/news/772315/

相关文章:

  • 建设银行网站用360浏览器建设信用卡中心网站
  • 创建公司网站 教程广州建设局
  • 详述网站建设的过程简答题ui培训设计怎么样
  • 动易网站官网ppt主题大全素材
  • 怎样用eclipse做网站可以做宣传图的网站
  • 哪里可以做游戏视频网站做网站平台应该注意哪些
  • 网站后期推广是谁来做网页制作步骤作答题
  • 全屋装修设计定制整装成都网站优化多少钱
  • html5购物网站模板一个网站两个数据库
  • 个人网站怎么做微信支付网站建设项目介绍
  • 建网站合同网站适配移动端和PC端
  • 网站建设培训机构哪里好html5开发wap网站
  • 免费自助建站源码学而思网校官网
  • 中国最大的网站制作公司青海省高等级公路建设管局网站
  • 建设网站对服务器有什么要求吗wordpress去除更新提示
  • 找个为公司做网站的手机端原神
  • 邯郸手机建站价格公众号开发者权限哪里添加
  • wordpress模板电子书下载站微信app官方免费下载
  • 从哪些方面进行网站建设如何做网站的实时画面
  • 设计网站公司收费西安小程序开发公司有哪些
  • 如何建网站赚取佣金哪个网站可以做免费宣传
  • 万网手机网站seo方法
  • 免费制作网站app百度首页纯净版
  • 支持api网站开发wordpress排版Markdown
  • 赤峰做网站的logo设计软件在线制作
  • iis网站批量导入苏州最新新闻事件今天
  • 甘肃省住房和城乡建设厅注册中心网站首页沈阳专业关键词推广
  • 网站怎么能在百度搜到网站开发费怎么做会计分录
  • 嘉定专业网站制作公司七星彩网站开发
  • 网站建设人员培训企业网站开发模型图