前提概要
上一篇关于SqlSessionFactoryBean的作用与源码我已经作了详细的讲解,这里我们再对@MapperScan
进行开刀解析一番~~
使用方式
当使用Java进行配置Mybatis时可以使用@MapperScan
注解进行对MyBatis的Mapper interfaces进行注册。
例子如下:
@Configuration
@MapperScan("org.mybatis.spring.sample.mapper")
public class AppConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.addScript("schema.sql")
.build();
}
@Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
return sessionFactory.getObject();
}
}
源码讲解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {
// 该属性为#basePackages()的别名,可以使用更简便的方式描述如下:
// @MapperScan("org.my.pkg") 等价于
// @MapperScan(basePackages = "org.my.pkg")
String[] value() default {};
// MyBatis interfaces的包路径名
// 注意:只有的至少有一个方法的接口类才会被注册,具体的实现类将会被忽略
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends Annotation> annotationClass() default Annotation.class;
Class<?> markerInterface() default Class.class;
// 当你有多个Datasource时,需要指定使用哪一个SqlSessionTemplate
String sqlSessionTemplateRef() default "";
// 当你有多个datasource时,需要指定使用哪一个SqlSessionFactory
String sqlSessionFactoryRef() default "";
// 指定一个自定义的MapperFactoryBean
Class<? extends MapperFactoryBean> factoryBean() default MapperFactoryBean.class;
}
注解在什么时候被引用?
这里我们看到MapperScan类头上的注解@Import(MapperScannerRegistrar.class)
而@Import
这个注解是spring-context包中一个注解类,其功能如下:
package org.springframework.context.annotation;
/**
* 1. 指明要导入一个或多个@Configuration类;
* 2. 提供等价于Spring XML中的<import/>元素的功能。
* 允许导入@Configuration、ImportSelector和ImportBeanDefinitionRegistrar实现,
* 以及常规组件类,类似于AnnotationConfigApplicationContext#register.
* 3. 导入的类中声明的定义应该可以通过使用@Autowired注入。
* 4. 可以在class级别或method中声明;
* 5. 如果XML或其他非bean类定义资源需要导入,可以使用@ImportResource注解实现
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
Class<?>[] value();
}
至此,我们的Mapper interfaces就会通过spring 的factory模式注册。所以我们定义的各个xxxMapper.java接口类就可以通过@Autowired注入使用。
网友评论