查看一些基本注释@AliasFor@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic@interfaceAliasFor{@AliasFor("attribute")Stringvalue()默认””;@AliasFor("value")字符串属性()默认"";类annotation()defaultAnnotation.class;}AliasFor这个注解很奇怪,value的别名是attribute,attribute的别名是value那么它的行为是在哪里定义的呢?我们可以在AnnotationTypeMapping中找到答案//这里我们使用AnnotationsScanner的getDeclaredAnnotation方法获取所有的AliasFor注解方法//AnnotationsScanner是spring中的一个非public抽象类,我们的代码中不能直接使用//没有Spring提供子类privateMap>resolveAliasedForTargets(){Map>aliasedBy=newHashMap<>();for(inti=0;inewArrayList<>()).add(attribute);}}returnCollections.unmodifiableMap(aliasedBy);}//为了简洁起见,我将省略其余的源代码。可以看到,通过反射获取到的Method的getAnnotation方法是用来获取实例的).get(目标属性名称);//......if(isAliasPair(target)&&checkAliasPair){AliasFortargetAliasFor=target.getAnnotation(AliasFor.class);如果(targetAliasFor!=null){方法mirror=resolveAliasTarget(target,targetAliasFor,false);if(!mirror.equals(attribute)){thrownewAnnotationConfigurationException(String.format("%s必须声明为@AliasFor%s,而不是%s。",StringUtils.capitalize(AttributeMethods.describe(target)),AttributeMethods.describe(attribute),AttributeMethods.describe(镜像)));}}}returntarget;}通过学习@AliasFor,我们知道可以先激活Method,然后or获取其修饰的注解方法根据这个方法,我们可以通过下面的代码找到类DockingHandlers中所有被注解为@DockIngMessage的方法//DockIngMessage是自定义注解Method[]methods=DockingHandlers.class.getMethods();for(Methodmethod:methods){DockIngMessagedockIngMessage=method.getAnnotation(DockIngMessage.class);if(dockIngMessage!=null){System.out.println(dockIngMessage.name());}}@Bean@Target({ElementType.METHOD,ElementType.ANNOTATION_TYPE})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceBean{@AliasFor("name")String[]value()default{};@AliasFor("value")String[]name()default{};@DeprecatedAutowireautowire()defaultAutowire.NO;布尔autowireCandidate()默认为真;StringinitMethod()默认"";StringdestroyMethod()defaultAbstractBeanDefinition.INFER_METHOD;}@Bean注解是Spring中使用比较广泛的注解之一下面我们看看如何在Spring源码中找到@Bean注解的publicstaticbooleanisBeanAnnotated(Methodmethod){returnAnnotatedElementUtils.hasAnnotation(方法,Bean.class);}使用AnnotatedElementUtils工具类,那么我们可以修改上面的代码类)){DockIngMessagedockIngMessage=AnnotatedElementUtils.getMergedAnnotation(方法,DockIngMessage.class);System.out.println(dockIngMessage.name());}}//比起判断!=null,这种写法相对要优雅很多。至于Bean是如何工作的,需要先存起来,等以后研究Spring容器的时候再讨论annotation=Component.class)Stringvalue()default"";}Controller的test里面有这么一段代码provider.addIncludeFilterComponTypeFilter(newAnnotation.class));provider.addExcludeFilter(新注释ionTypeFilter(Repository.class));provider.addExcludeFilter(newAnnotationTypeFilter(Service.class));provider.addExcludeFilter(newAnnotationTypeFilter(Controller.class));Setcandidates=provider.findCandidateComponents(TEST_BASE_PACKAGE);assertThat(候选人.size()).isEqualTo(3);assertThat(containsBeanClass(candidates,NamedComponent.class)).isTrue();assertThat(containsBeanClass(candidates,ServiceInvocationCounter.class)).isTrue();assertThat(containsBeanClass(candidates,BarComponent.class)).isTrue();assertThat(containsBeanClass(candidates,FooServiceImpl.class)).isFalse();assertThat(containsBeanClass(candidates,StubFooDao.class)).isFalse();assertThat(containsBeanClass(candidates,NamedStubDao.class)).isFalse();}也就是说可以通过包扫描的方式获取某个包下某个注解修饰的类。查找所有被某个注解修饰的类,使用ClassPathScanningCandidateComponentProvider进行扫描。要查找被注解修改的方法,首先找到那个类,然后获取所有方法,并使用AnnotatedElementUtils.hasAnnotation来判断该方法是否被注解修改。下面是一个简单的例子。ClassPathScanningCandidateComponentProviderprovider=newClassPathScanningCandidateComponentProvider(false);provider.addIncludeFilter(newAnnotationTypeFilter(DockingAnnotation.class));Setcandidates=provider.findCandidateComponents("package_name");for(BeanDefinitiondefinition:candidates){尝试{Classclz=Class.forName(definition.getBeanClassName());方法[]methods=clz.getMethods();对于(方法方法:方法){如果(AnnotatedElementUtils.hasAnnotation(方法,DockIngMessage.class)){DockIngMessagedockIngMessage=AnnotatedElementUtils.getMergedAnnotation(方法,DockIngMessage.class);系统输出。println(dockIngMessage.name());}}}catch(ClassNotFoundExceptione){e.printStackTrace();}}炸鸡辣子鸡原创文章,转载请注明出处