spring -- 自定义注解

时间:2022-05-13 20:37:46

我们直接通过代码解释自定义注解的使用及各个含义

package com.sysware.cloud.dts.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Inherited
@Documented
public @interface DtTransactional {
    
    /*
     * Whether need to rollback
     */
    public boolean includeLocalTransaction() default true;
    
    public boolean confirmMethodExist() default false;
    
    /*
     * Allow [confirmMethod] is null if [confirmMethodExist] is false
     */
    public String confirmMethod() default "";

    public String cancelMethod() default "";
    
}

说明1:@Target、@Retention、@Inherited、@Documented为元注解(meta-annotation),它们是负责注解其他注解的。

1:Target注解 :指明注解支持的使用范围,取值可以参考ElementType :

  • ElementType.TYPE //类、接口、枚举
  • ElementType.FIELD //属性
  • ElementType.METHOD //方法
  • ElementType.PARAMETER //参数
  • ElementType.CONSTRUCTOR //构造器
  • ElementType.LOCAL_VARIABLE //局部变量
  • ElementType.ANNOTATION_TYPE //注解
  • ElementType.PACKAGE //包

2:Retention注解 :指明注解保留的时间长短,取值参考枚举RetentionPolicy :

  • SOURCE //源文件中保留
  • CLASS //class编译时保留
  • RUNTIME //运行时保留

3:Inherited 注解:指明该注解类型被自动继承。如果一个annotation注解被@Inherited修饰,那么该注解作用于的类的子类也会使用该annotation注解。

4:Document 注解:指明拥有这个注解的元素可以被javadoc此类的工具文档话。

说明2:在自定义注解中定义的属性有 default ,使用该注解的时候可以不填写该属性,否则该属性为必填,不填会提示错误。

上面自定义注解就定义好了,接下来就可以在Target指定的范围内使用该注解了,比如上面定义的注解是使用在 METHOD 上的,可以这样使用

package com.sysware.cloud.dts.service.impl;

import com.sysware.cloud.commons.util.idwork.LongIdGenerator;
import com.sysware.cloud.dts.annotation.DtTransactional;
import com.sysware.cloud.dts.entity.PointEntity;
import com.sysware.cloud.dts.repository.PointRepository;
import com.sysware.cloud.dts.service.PointService;
import com.sysware.cloud.po.CriteriaQuery;
import com.sysware.cloud.service.impl.BaseServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.CancellationException;

@Service
public class PointServiceImpl extends BaseServiceImpl<PointEntity,PointRepository,Long> implements PointService {


    @Override
    @Transactional
    @DtTransactional(cancelMethod = "cancel")
    public PointEntity add(PointEntity entity) {
        //根据用户ID查询是否积分记录,没有则生成积分,有的话,则修改添加积分
        PointEntity pointEntity = super.repository.findPointEntitiesByUserId(entity.getUserId());
        if(pointEntity==null){
            entity.setId((LongIdGenerator.getId()));
            return super.repository.save(entity);
        }else {
            pointEntity.setPoint(pointEntity.getPoint()+entity.getPoint());
           return super.repository.save(pointEntity);
        }
    }

    public PointEntity cancel(PointEntity entity) {
        PointEntity pointEntity = super.repository.findPointEntitiesByUserId(entity.getUserId());
        if (pointEntity != null) {
            pointEntity.setPoint(pointEntity.getPoint() - entity.getPoint());
            return super.repository.save(pointEntity);
        }
        return null;
    }
}

最后就是如何解析自定义注解了, 解析过程可以使用AOP统一处理,参考我的博客spring --解析自定义注解SpringAOP(配合@Aspect