我们直接通过代码解释自定义注解的使用及各个含义
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