Mapper 自定义注解器

本文详细介绍了如何创建和使用Java自定义注解Mapper,包括注解器的作用、自定义注解的实现、解析器的编写、注解库的构建和上传到私仓maven的步骤。通过注解和编译期处理,实现模板代码的自动化构建,简化项目中的组件匹配逻辑。
摘要由CSDN通过智能技术生成

java 自定义注解器 Mapper,并提交私仓 maven

1. java 自定义注解器

1.1 注解器作用

通过元注解对类、变量等进行标记,在代码编译期通过解析器 AbstractProcessor 进行解析,快速实现模板代码的构建等作用

1.2 自定义注解

通过 @interface 实现注解,如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MapType {
   
	String name() default "";
}
1.3 实现一个解析器 Processor
  1. 必须继承 AbstractProcessor,通过方法 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) 对定义的注解类型进行解析。
  2. 需要重写 getSupportedAnnotationTypes() 声明对哪些些注解生效
  3. init(ProcessingEnvironment processingEnv) 中获取工具类,如:
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
         
            super.init(processingEnv);
    	Types typeUtils = processingEnv.getTypeUtils();
    	Elements elementUtils = processingEnv.getElementUtils();
    	Filter filer = processingEnv.getFiler();
    	Messager messager = processingEnv.getMessager();
    }
    
1.4 解析注解,构建类

从自定义解析器可以获取并处理自定义注解类型,动态构建类可以通过 JavaWriter 或者 JavaPoet
JavaPoet 是对 JavaWriter 的进一步封装。
如何使用参考官网介绍:JavaPoet github 链接

2. 实现注解库

新建 java library,建议使用 idea 的 maven/gradle 工程

2.1 mapper-annotation 注解库

新建 java library,命名为 mapper-annotation,用于存放注解。
也可以把注解、解析器等放在同一个库中,但一般解析器所依赖的库只需要在编译期使用,不需要打包进主工程,所以会选择库拆分。

2.2 mapper-compiler 解析库

同样新建 java library,再添加 JavaPoet 依赖,在 module 的 build.gradle 中添加 implementation group: 'com.squareup', name: 'javapoet', version: '1.8.0'
在项目调试阶段,增加注解库依赖 implementation project(":mapper-annotation"),在调试完成后,可以将直接依赖替换为线上依赖,如 implementation 'com.lib:mapper-annotation:1.0.0'

2.3 mapper aar 库

这个库主要是存放对外访问的接口。给 android 项目使用,如果没有这类需求可以不加,或者也可以放入 annotation 库中,不是必要创建的库。
新建 android library,同样需要添加对 annotation 依赖,在上线后替换为线上版本,如上。

3. 自定义 mapper 注解库需求及实现

3.1 构建需求

在业务项目中使用了大量的组件,在使用中需要根据用户的组件类型去匹配,呈现该组件。在原先开发中,流程如下:

private void showComponent(Item item){
   
	String type = item.getType();
	if("A".equals(type){
   
		Component cc = new A(item);
		cc.show();
	}else if("B".equals(type){
   
		Component cc = new B(item);
		cc.show();
	}else if("C".equals(type){
   
		Component cc = new C(item);
		cc.show();
	}else {
   
		//...
	}
}

在少量组件的情况下,使用 if-else 结构清晰,但随着项目扩展,这段判断特别长,因此有了第一次改造,修改后如下:

private static HashMap<Strng,Class> map = new HashMap<>();

static{
   
	map.put("A",A.class);
	map.put("B",B.class);
	map.put("C",C.class);
	//...
}

private void showComponent(Item item)
要配置自定义拦截拦截指定目录的 mapper 文件,可以按照以下步骤进行: 1. 创建一个自定义拦截类,实现 Mybatis 的 Interceptor 接口,重写其中的 intercept() 方法,在该方法中实现自定义的拦截逻辑。 2. 在该拦截类上使用 @Intercepts 注解定义需要拦截的方法以及拦截的时机,例如: ```java @Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}), @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}) }) public class MyInterceptor implements Interceptor { // ... } ``` 以上示例中,定义了拦截 Executor 类中的 query() 和 update() 方法,并传入了对应的参数类型。 3. 在 Mybatis 的配置文件中,将该拦截类添加到插件列表中,并指定需要拦截的 mapper 文件路径,例如: ```xml <configuration> <plugins> <plugin interceptor="com.example.MyInterceptor"> <property name="mapperPath" value="com/example/mapper/**/*Mapper.xml"/> </plugin> </plugins> </configuration> ``` 以上示例中,将 MyInterceptor 添加到插件列表中,并指定需要拦截的 mapper 文件路径为 com/example/mapper/ 目录下的所有 Mapper.xml 文件。 在 MyInterceptor 类中,可以通过获取配置文件中的 mapperPath 属性来获取需要拦截的 mapper 文件路径,然后根据该路径判断是否需要拦截当前执行的方法。 ```java public class MyInterceptor implements Interceptor { private String mapperPath; @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; String mapperId = mappedStatement.getId(); if (mapperId.matches(mapperPath)) { // 需要拦截的方法 } return invocation.proceed(); } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); } @Override public void setProperties(Properties properties) { mapperPath = properties.getProperty("mapperPath"); } } ``` 以上示例中,通过获取配置文件中的 mapperPath 属性,并使用正则表达式判断当前执行的方法是否需要拦截。如果需要拦截,则执行自定义的拦截逻辑。否则,直接调用被拦截方法的原始逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值