最新传奇游戏,新开sf网站.欧比奥传奇发布网
当前位置:网站首页 > 传奇私服 > 正文

webfilter没有进去

作者:admin发布时间:2021-10-21分类:传奇私服浏览:221评论:10


导读:首先我们来看下注解(删除了相关注解):()()(){(basePackages)String[]value()default{};AliasFor(value)String[]ba...

webfilter没有进去

首先我们来看下注解(删除了相关注解):

()()(){(basePackages)String[]value()default{};AliasFor(value)String[]basePackages()default{};Class?[]basePackageClasses()default{};}

简单来说此注解就是指定扫描路径的通过value、basePackages或者basePackageClasses。主要还是看下ServletComponentScanRegistrar类这才是关键。

classServletComponentScanRegistrarimplementsImportBeanDefinitionRegistrar{privatestaticfinalStringBEAN_NAMEservletComponentRegisteringPostProcessorOverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){//获取包路径SetStringpackagesToScangetPackagesToScan(importingClassMetadata);//若已注册则更新否则新增if(registry.containsBeanDefinition(BEAN_NAME)){updatePostProcessor(registry,packagesToScan);}else{addPostProcessor(registry,packagesToScan);}}privatevoidupdatePostProcessor(BeanDefinitionRegistryregistry,SetStringpackagesToScan){BeanDefinitiondefinitionregistry.getBeanDefinition(BEAN_NAME);ValueHolderconstructorArgumentsdefinition.getConstructorArgumentValues().getGenericArgumentValue(Set.class);SuppressWarnings(unchecked)SetStringmergedPackages(SetString)constructorArguments.getValue();mergedPackages.addAll(packagesToScan);constructorArguments.setValue(mergedPackages);}privatevoidaddPostProcessor(BeanDefinitionRegistryregistry,SetStringpackagesToScan){GenericBeanDefinitionbeanDefinitionnewGenericBeanDefinition();//设置类beanDefinition.setBeanClass(ServletComponentRegisteringPostProcessor.class);//设置构造函数参数beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(packagesToScan);beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);//注册registry.registerBeanDefinition(BEAN_NAME,beanDefinition);}privateSetStringgetPackagesToScan(AnnotationMetadatametadata){//获取注解ServletComponentScan的属性信息AnnotationAttributesattributesAnnotationAttributes.fromMap(metadata.getAnnotationAttributes(ServletComponentScan.class.getName()));//获取属性basePackages和basePackageClassesString[]basePackagesattributes.getStringArray(basePackagesClass?[]basePackageClassesattributes.getClassArray(basePackageClassesSetStringpackagesToScannewLinkedHashSetStringpackagesToScan.addAll(Arrays.asList(basePackages));//basePackageClasses最后也是根据basePackageClasses来获取塔对应的包路径for(Class?basePackageClass:basePackageClasses){packagesToScan.add(ClassUtils.getPackageName(basePackageClass));}//默认不填写时获取的是被注解类所在包路径所以一般放在启动类上if(packagesToScan.isEmpty()){packagesToScan.add(ClassUtils.getPackageName(metadata.getClassName()));}returnpackagesToScan;}}

可以看见它是一个ImportBeanDefinitionRegistrar的实现类ImportBeanDefinitionRegistrar可以动态地装载Bean。再来看看ServletComponentRegisteringPostProcessor类此类是个BeanFactoryPostProcessorBeanFactory的后置处理器简单理解就是扩展点吧。启动的时候会调用postProcessBeanFactory方法。

ServletComponentRegisteringPostProcessor

源码就不贴了简单来说它的作用就是扫描被WebServlet、WebFilter及WebListener的类最后通过对应的ServletRegistrationBean、FilterRegistrationBean及ServletListenerRegistrationBean进行注册。看见这些是不是很熟悉了。

//部分代码static{ListServletComponentHandlerservletComponentHandlersnewArrayListServletComponentHandlerservletComponentHandlers.add(newWebServletHandler());servletComponentHandlers.add(newWebFilterHandler());servletComponentHandlers.add(newWebListenerHandler());HANDLERSCollections.unmodifiableList(servletComponentHandlers);}

关键看这个方法scanPackage:

privatevoidscanPackage(ClassPathScanningCandidateComponentProvidercomponentProvider,StringpackageToScan){for(BeanDefinitioncandidate:componentProvider.findCandidateComponents(packageToScan)){if(candidateinstanceofScannedGenericBeanDefinition){for(ServletComponentHandlerhandler:HANDLERS){handler.handle(((ScannedGenericBeanDefinition)candidate),(BeanDefinitionRegistry)this.applicationContext);}}}}

可以看见通过componentProvider.findCandidateComponents(packageToScan)方法获取到对应的注解类同时判断是否为以上说的三种最后调用其doHandle方法完成注册功能。以下是WebFilterHandler的doHandler方法。

现在我们看看findCandidateComponents方法怎么获取对应注解类的。

断点之后可以看见是AnnotationConfigEmbeddedWebApplicationContext类

继续断点进去最后是使用PathMatchingResourcePatternResolver类进行资源获取的。

通过递归的方式获取所有的类

最后关键就是这个Arrays.sort(dirContents)了。所以简单来说可以通过class类名来达到排序效果。但这种方案要限制类名还是使用FilterRegistrationBean之类的来设置吧。

总结


已有10位网友发表了看法:

欢迎 发表评论: