使用场景:
- 添加中间件,配置某个注解的自定义扫描路径,例如 @Refrence,Seata 的 @Refrence。
- 使用自定义注解,配置自定义注解的扫描路径。
配置代码:
扫描加载类
IgnoreTenantTablesImportSelector.java
package com.leelen.hermes.mybatis.anno;
import com.leelen.hermes.mybatis.constant.TenantConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;
import java.util.Set;
/**
* @author linqy@leelen.cn
* @version 1.0.0
* @ClassName IgnoreTenantTablesImportSelector.java
* @Description
* @createTime 2023年04月20日 20:21:00
*/
@Slf4j
public class IgnoreTenantTablesImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 不使用默认的TypeFilter
ClassPathScanningCandidateComponentProvider provider =
new ClassPathScanningCandidateComponentProvider(false);
// 添加扫描规律规则,这里指定了内置的注解过滤规则
provider.addIncludeFilter(new AnnotationTypeFilter(IgnoreTenantTables.class));
// 扫描指定包,如果有多个包,这个过程可以执行多次
String[] packages = getPackageToScan(annotationMetadata);
for (String aPackage : packages) {
Set<BeanDefinition> beanDefinitionSet = provider.findCandidateComponents(aPackage);
beanDefinitionSet.forEach(beanDefinition -> {
String tableName = getTableNameByAnntation(beanDefinition);
TenantConstant.ignoreTables.add(tableName);
});
}
return new String[0];
}
private String[] getPackageToScan(AnnotationMetadata metadata) {
//通过自定义注解获取自定义包路径
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
metadata.getAnnotationAttributes(IgnoreTenantTablesScan.class.getName()));
String[] basePackages = attributes.getStringArray("basePackages");
if (basePackages.length != 0) {
return basePackages;
}
return new String[]{ClassUtils.getPackageName(metadata.getClassName())};
}
private String getTableNameByAnntation(BeanDefinition definition) {
String beanClassName = definition.getBeanClassName();
try {
Class<?> aClass = Class.forName(beanClassName);
IgnoreTenantTables annotation = aClass.getAnnotation(IgnoreTenantTables.class);
if (annotation == null) {
return null;
}
//获取到注解name的值并返回
return annotation.tableName();
} catch (ClassNotFoundException e) {
log.error("ClassNotFoundException", e);
}
return null;
}
}
自定义注解
IgnoreTenantTablesScan.java
package com.leelen.hermes.mybatis.anno;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
/**
* @author linqy@leelen.cn
* @version 1.0.0
* @ClassName IGnoreTenantyablesScan.java
* @Description
* @createTime 2023年04月20日 19:41:00
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Import(IgnoreTenantTablesImportSelector.class)
@Documented
public @interface IgnoreTenantTablesScan {
String[] basePackages() default {};
}
IgnoreTenantTables.java
package com.leelen.hermes.mybatis.anno;
import java.lang.annotation.*;
/**
* @author linqy@leelen.cn
* @version 1.0.0
* @ClassName IgnoreTenantTables.java
* @Description
* @createTime 2023年04月20日 19:37:00
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IgnoreTenantTables {
String tableName() default "";
}
用法
标注在某个
@IgnoreTenantTables(tableName="t_user")
@Getter
@Setter
@TableName("t_user")
@IgnoreTenantTables(tableName="t_user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
}
启动类添加注解
@IgnoreTenantTablesScan(basePackages = {"com.leelen.hermes.**"})
@SpringBootApplication
@MapperScan(basePackages = {"com.leelen.hermes.demo.dao"})
@IgnoreTenantTablesScan(basePackages = {"com.leelen.hermes.**"})
public class MybatisplusApplication {
public static void main(String[] args)
{
SpringApplication application = new SpringApplication(MybatisplusApplication.class);
application.run(args);
}
}