mybatis-spring:@MapperScan注解
在demo: springboot+mybatis的示例中,dao层接口使用了注解@MapperScan:指定扫描com本文来源gao($daima.com搞@代@#码$网.xuxd.demo.dao.UserDao所在包路径下的所有接口类。
本文分析下@MapperScan注解做了哪些动作。
@MapperScan源码
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented @Import(MapperScannerRegistrar.class) public @interface MapperScan { /** *缺省属性(==basePackages),basePackages的别名 */ String[] value() default {}; /** * 哪些包路径下的接口被扫描注册(接口至少有一个方法),具体实现类(非接口)忽略 */ String[] basePackages() default {}; /** * 指定类所在包下所有接口被扫描注册(接口至少有一个方法),具体实现类(非接口)忽略 */ Class<?>[] basePackageClasses() default {}; /** * 扫描到的满足条件的接口,首先要把它们相关bean定义注册到spring容器中吧,注册bean定义 * 的时候,需要定义bean名称,这个是用来自定方生成bean名称的策略组件,个人觉得很少用 */ Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class; /** * 这个注解指定的接口也要被扫描 */ Class<? extends Annotation> annotationClass() default Annotation.class; /** * 继承这个接口的接口也要被扫描 */ Class<?> markerInterface() default Class.class; /** * 多数据源的时候可能用到这个,后面单独说明这个 */ String sqlSessionTemplateRef() default ""; /** * 多数据源的时候可能用到这个,后面单独说明这个 */ String sqlSessionFactoryRef() default ""; /** * 多数据源的时候可能用到这个,后面单独说明这个 */ Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class; }
这个注解的重点是@Import(MapperScannerRegistrar.class)
使用这个注解导入MapperScannerRegistrar主要完成两件事:
1. 扫描指定接口
2. 注册这些接口的bean定义到spring容器
接下来进入MapperScannerRegistrar类看下是如何完成这两动作:
MapperScannerRegistrar.class
public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {}
这个类实现了ImportBeanDefinitionRegistrar接口:
public interface ImportBeanDefinitionRegistrar { public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry); }
@MapperScan注解类上使用了@Import注解导入了这个接口的实现类(MapperScannerRegistrar.class),因此spring解析MybatisConfig(源码:demo: springboot+mybatis)这个类的时候,解析到这个类上使用了注解@MapperScan,从MapperScan注解类上(注解都是一个接口,java会创建代理类)发现了@Import注解及MapperScannerRegistrar类(因为Import注解是导入配置类的)。