说明
大家在使用mybatis或者openFeign时只定义了一个接口类,并无实现类,可以把接口注入到service中并且能调用方法返回值。
一个接口并无实现类,为什么可以实例化并且交给了spring管理。mybatis,OpenFeign又是怎么实现的?
看mybatis源代码理解的,删减了很多,保留一些关键初始化步骤。
直接上代码,链接(gitee上面)
1.先自定义注解,用于SpringBootApplication启动类。启动类加上CkScan注解,注解值即需要扫描那些包接口。springboot在启动时,发现注解里面Import导入CkScannerRegistrar类,会解析此类,此步就是实现入口。CkScannerRegistrar类下面会讲解
@Retention(RetentionPolicy.RUNTIME)
@Target({
ElementType.TYPE})
@Documented
@Import({
CkScannerRegistrar.class})
public @interface CkScan {
String[] value() default {
};
String[] basePackages() default {
};
}
@org.springframework.boot.autoconfigure.SpringBootApplication
@MapperScan("com.ck.datacenter.**.dao")
@CkScan("com.ck.datacenter.itf")
@EnableOpenApi
public class SpringBootApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootApplication.class);
application.run();
}
}
CkScannerRegistrar类实现,解析此类时发现实现了spring的ImportBeanDefinitionRegistrar接口并且重新写了registerBeanDefinitions方法,会调用此方法。里面关键点new CkClassPathScanner类并且调用了doScan。
public class CkScannerRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
// 获取SpringBootApplication自定义注解CkScan值
AnnotationAttributes attrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(CkScan.class.getName()));
if (attrs != null) {
List<String> basePackages = new ArrayList<>();
basePackages.addAll(Arrays.stream(attrs.getStringArray(