1、什么是注解
注解(Annotation)是一种Java语言元素,用于为Java源代码提供元数据(metadata)。它们为Java程序员提供了一种定义和描述程序元素(如类、方法、变量等)的方式。注解通常用于文档生成、代码分析、编译检查等场合,可以帮助开发者更好地理解Java代码的含义和目的。
注解在SpringBoot应用或Java应用开发中,经常会用到,有时业务复杂时,可能还需要定义可重复标记的注解,此时就很有必要了解定义可重复标记的注解的实现方式
2、自定义注解示例
比如,定义一个根据指定的数据源名称、Mapper接口包路径、SQL映射文件路径等MyBatis组件的扫描器:
/*
* Copyright (c) Bruce.CH 2022-2023. All rights reserved.
*/
/**
* 多数据源MyBatis组件注册扫描注解
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({CoffeeMapperScanRegistrar.class})
public @interface CoffeeMapperScan {
/**
* 定义数据源名称
*
* @return 数据源名称
*/
String dataSourceName();
/**
* 指定数据源类型,缺省为HikariDataSource
*
* @return 数据源类型
*/
Class<?> dataSourceType() default HikariDataSource.class;
/**
* 是否为主要数据源/缺省数据源,默认为否
*
* @return 是否为主要数据源/缺省数据源
*/
boolean primary() default false;
/**
* 定义使用此数据源的MyBatis的DAO/Mapper接口包路径
*
* @return MyBatis的DAO/Mapper接口包路径
*/
String[] basePackages();
/**
* 定义使用此数据源的MyBatis的sql映射文件的在classpath下的位置路径
*
* @return MyBatis的sql映射文件的所在位置
*/
String[] mapperLocations() default "mapper/**/*.xml";
}
其中CoffeeMapperScanRegistrar类为实现此注解功能的bean注册器,实现数据源对象、MyBatis组件的初始化,并注册到Spring容器中。
要使用该注解,直接在配置类上标记即可:
/**
* MyBatisConfig
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Configuration
@CoffeeMapperScan(dataSourceName = "coffee", basePackages = "com.example.demo.mapper.coffee", mapperLocations =
"mapper/coffee/*.xml")
public class MyBatisConfig {
}
3、可重复标记的注解实现方式
以上示例中的@CoffeeMapperScan注解,每个配置类只能标记一次该注解,初始化一个数据源并绑定对应MyBatis组件,如果需要操作多个数据源,则需要创建多个配置类分别标记,显得有些冗余或不够灵活。
下面的两种实现方式,可以避免创建多个配置类。
3.1、注解数组
再自定义一个注解@CoffeeMapperScans,声明一个@CoffeeMapperScan数组属性
/**
* 可重复多数据源MyBatis组件注册扫描注解
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({CoffeeMapperScansRegistrar.class})
public @interface CoffeeMapperScans {
/**
* CoffeeMapperScan集合
*
* @return CoffeeMapperScan
*/
CoffeeMapperScan[] value();
}
这样,就可以直接在一个配置类上标记多个CoffeeMapperScan注解,使用示例如下:
/**
* MyBatisConfig
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Configuration
@CoffeeMapperScan(dataSourceName = "nuts", basePackages = "com.example.demo.mapper.nuts", mapperLocations = "mapper" +
"/nuts/*.xml",
primary = true)
@CoffeeMapperScans({
@CoffeeMapperScan(dataSourceName = "coffee", basePackages = "com.example.demo.mapper.coffee", mapperLocations =
"mapper/coffee/*.xml")
})
public class MyBatisConfig {
}
3.2、@Repeatable注解
第二种实现方式,就是直接在自定义注解@CoffeeMapperScan时,标记@Repeatable注解,指定一个包含此注解的容器注解即@CoffeeMapperScans注解即可
/**
* 多数据源MyBatis组件注册扫描注解
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({CoffeeMapperScanRegistrar.class})
@Repeatable(CoffeeMapperScans.class)
public @interface CoffeeMapperScan {
/**
* 定义数据源名称
*
* @return 数据源名称
*/
String dataSourceName();
/**
* 指定数据源类型,缺省为HikariDataSource
*
* @return 数据源类型
*/
Class<?> dataSourceType() default HikariDataSource.class;
/**
* 是否为主要数据源/缺省数据源,默认为否
*
* @return 是否为主要数据源/缺省数据源
*/
boolean primary() default false;
/**
* 定义使用此数据源的MyBatis的DAO/Mapper接口包路径
*
* @return MyBatis的DAO/Mapper接口包路径
*/
String[] basePackages();
/**
* 定义使用此数据源的MyBatis的sql映射文件的在classpath下的位置路径
*
* @return MyBatis的sql映射文件的所在位置
*/
String[] mapperLocations() default "mapper/**/*.xml";
}
使用的时候可以参考实现方式1的方式,也可以像下面这样使用:
/**
* MyBatisConfig
*
* @author Bruce.CH
* @since 2023年08月13日
*/
@Configuration
@CoffeeMapperScan(dataSourceName = "nuts", basePackages = "com.example.demo.mapper.nuts", mapperLocations = "mapper" +
"/nuts/*.xml",
primary = true)
@CoffeeMapperScan(dataSourceName = "coffee", basePackages = "com.example.demo.mapper.coffee", mapperLocations =
"mapper/coffee/*.xml")
public class MyBatisConfig {
}
4、更多文章
自定义动态数据源:SpringBoot+MyBatis实现多租户动态数据源