3 个回答

自问自答,提出问题第二天就已通过跟踪源码找到答案,说说结果给后人以经验.
为什么会有这样的问题,来自于springcloud feign 远程调用场景,controller继承了api service,在service的方法上定义RequestMapping,controller中不定义,spring同样能扫描到,完成请求地址与方法的映射,这个过程蹊跷的地方在于,接口中定义的注解并不会被类继承,其唯一可以识别到的方式就是 扫描父类,但是一般似乎从来没这么用过,在关于spring源码解析的文章当中也很少有提及扫描组件会去查找父类中的注解,带着问题去跟踪源码,发现,在扫描组件过程中反复调用了 这么一个类AnnotatedElementUtils,其中的方法searchWithGetSemantics,语义化搜索,什么叫语义化搜索,该类的注释已明确给出了答案.
` * <p>{@code AnnotatedElementUtils} defines the public API for Spring's

  • meta-annotation programming model with support for annotation attribute
  • overrides. If you do not need support for annotation attribute
  • overrides, consider using {@link AnnotationUtils} instead. * <p>Find semantics are much more exhaustive, providing
  • get semantics plus support for the following:

*

  • <ul>
  • <li>Searching on interfaces, if the annotated element is a class
  • <li>Searching on superclasses, if the annotated element is a class
  • <li>Resolving bridged methods, if the annotated element is a method
  • <li>Searching on methods in interfaces, if the annotated element is a method
  • <li>Searching on methods in superclasses, if the annotated element is a method
  • </ul>`

这里有非常好的例子展示spring扫描的范围设定
符合以下条件的会被扫描并创建bean

  • 类有@Component注解
  • 且包名包含在@ComponentScan注解范围内
  • 或包含在@ComponentScan.Filter范围内

如果子类符合条件,但父类没有包含在扫描范围内, 子类会创建,但父类不会创建, 因为不符合instanceof条件,即不能说父类子类
如果父类被创建, 子类有@Component注解,但不在指定Filter范围内,也会创建,因为符合instanceof条件,因为子类一定是父类

@Component注解没有继承关系(@Inherited), 所以想被创建必须首先要有这个注解才行.
或创建你自己的可继承的注解过的接口.

如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Component 
@Inherited
public @interface BusinessService {
}
新手上路,请多包涵

另外 如果是spring boot的其实可以自己测试 看下结果的 http://ip:port/beans

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题