-
2021-03-11 16:54:10
1、写一个切面
@Aspect @Component public class LogInfoAspect { @Pointcut(value = "@annotation(com.main.entity.annotation.LogInfo)") public void LogInfoAspect(){ } // 在这里定义前置切面 @Before("LogInfoAspect()") public void beforeMethod(JoinPoint joinPoint) { // 这里执行保存日志的动作 System.out.println("before ......."); //得到被切方法的参数 System.out.println(joinPoint.getArgs()[0]); } }
2、写一个注解
@Retention(RetentionPolicy.RUNTIME) @Documented @Target(ElementType.METHOD) public @interface LogInfo { boolean value() default true; }
3、controller的引用
@LogInfo @RequestMapping(value = "/trrtt") public String trrtt(HttpServletRequest request, Model model) { return “success” }
更多相关内容 -
java 自定义切面增强(基于自定义注解aop)
2020-08-22 21:20:34写代码时会遇到一些有些重复机械的工作, 这个时候就可以运用切面技术来帮我们节约时间 本文介绍如何使用自定义注解增强方法, 实现自动完成重复的工作(还可以通过直接扫描包路径增强所有方法, 或者根据方法名, 入参等... -
java-自定义方法注解实现AOP面向切面编程
2021-12-14 11:02:41import java.lang.annotation.*; /** * @description: 保存或者修改字典权限判断注解 * @fileName: CommDictValidateAspect.java * @author: Sure * @createAt: 2021/12/13/013 16:14 * @updateBy: Sure * @remark: ...首先定义注解类
import java.lang.annotation.*;/** * @description: 保存或者修改字典权限判断注解 * @fileName: CommDictValidateAspect.java * @author: Sure * @createAt: 2021/12/13/013 16:14 * @updateBy: Sure * @remark: */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CommDictValidate { /** * 权限不足的默认提示信息 */ public static final String MESSAGE = "非超级管理员无法维护公共字典"; /** * 无权限时的提示信息 * * @return */ String message() default MESSAGE; }
定义切面类
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.data.annotation.Id; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.lang.reflect.Field; import java.lang.reflect.Method; import static /** * @description: 保存字典权限控制切面 * @fileName: CommDictValidateAspect.java * @author: Sure * @createAt: 2021/12/13/013 16:16 * @updateBy: Sure * @remark: * */ @Component //@Configuration @Aspect @Slf4j public class CommDictValidateAspect { //改成自己注解的地址 @Pointcut("@annotation(com.**.**.base.common.server.common.annotation.CommDictValidate)") public void doAspect() { log.warn("进入字典保存权限校验注解:{}的处理切点", CommDictValidate.class.getName()); } /** * 处理 CommDictValidate 注解的切面 * @Param: 连接点 * @return: 返回值 */ @Around("doAspect()") public Object around(ProceedingJoinPoint point){ try { Long id=null; Field field = null; LoginUserInfo loginUserInfo= LoginUserContext.getLoginUserInfo(); log.warn("进入字典保存权限校验注解:{}的处理切面", CommDictValidate.class.getName()); Object[] args = point.getArgs(); Object arg = args[0]; //自己的逻辑判断 if (ObjectUtils.isNotEmpty(arg)){ JSONObject jsonObject=JSON.parseObject(JSON.toJSONString(arg)); Long hospitalId = jsonObject.getLong("hospitalId"); }); } } return null; } catch (Throwable throwable){ log.error("字典保存权限校验异常",throwable); throw BusinessException.build(DictSaveOrUpdateErrorCodeEnum.PERMISSION_ASPECT_EX,throwable.getMessage()); } } /** * 获取注解中的参数 * * @param joinPoint 连接点 * @return 注解元信息 */ private String getAnnotationMessage(JoinPoint joinPoint) { MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); Method method = methodSignature.getMethod(); CommDictValidate annotation = method.getAnnotation(CommDictValidate.class); return annotation.message(); } }
最后放在方法的注释上即可生效
-
java 自定义AfterReturning切面注解
2022-04-07 17:20:03自定义一个注解并实现注解返回后处理逻辑功能 自定义一个注解 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CommunityOperation { /** * 主键 */ String ...自定义一个注解并实现注解返回后处理逻辑功能
自定义一个注解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface CommunityOperation { /** * 主键 */ String id() default "id"; /** * 类型 */ ContentTypeEnum type(); /** * 类型为空则使用typeName获取 */ String typeName() default "type"; }
JDK的元注解主要有@Target,@Retention,@Document,@Inherited用来修饰注解
@Target:表示java可以应用的元素类型ElementType.TYPE:应用于类、接口(包括注解类型)、枚举
ElementType.FIELD:应用于属性(包括枚举中的常量)
ElementType.METHOD:应用于方法
ElementType.PARAMETER:应用于方法的形参
ElementType.CONSTRUCTOR:应用于构造函数
ElementType.LOCAL_VARIABLE:应用于局部变量
ElementType.ANNOTATION_TYPE:应用于注解类型
ElementType.PACKAGE:应用于包
ElementType.TYPE_PARAMETER:1.8版本新增,应用于类型变量)
ElementType.TYPE_USE:1.8版本新增,应用于任何使用类型的语句中(例如声明语句、泛型和强制转换语句中的类型)@Retention:表明该注解的生命周期
RetentionPolicy.SOURCE:编译时被丢弃,不包含在类文件中
RetentionPolicy.CLASS:JVM加载时被丢弃,包含在类文件中,默认值
RetentionPolicy.RUNTIME:JVM 加载,包含在类文件中,在运行时可以被获取到@Document:表明该注解标记的元素可以被Javadoc 或类似的工具文档化
@Inherited:表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解增加切面处理注解
@AfterReturning
import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Aspect @Scope @Component @Slf4j public class CommunityOperationAspect { private ContentSendMsgFactory contentSendMsgFactory; @Pointcut(value = "@annotation(com.xxxx.xxx.xxxxxx.annoation.CommunityOperation)") public void activitySendMessage() {} @AfterReturning(value = "activitySendMessage()&&@annotation(communityOperation)",returning = "result") public Object beforeRequestIdVerify(JoinPoint joinPoint, Object result, CommunityOperation communityOperation) { try { JSONObject jsonObject=JSONObject.parseObject(JSONObject.toJSONString(result)); if(jsonObject.getIntValue("code")!= DefaultHttpResultStatus.SUCCESS.getCode()){ return result; } String id=StringUtils.EMPTY; Integer code=communityOperation.type().getCode(); if(joinPoint.getArgs()[0] instanceof String){ id=String.valueOf(joinPoint.getArgs()[0]); }else{ JSONObject params=JSONObject.parseObject(JSONObject.toJSONString(joinPoint.getArgs()[0])); id=params.getString(communityOperation.id()); if(communityOperation.type().getCode()==null){ code=params.getInteger(communityOperation.typeName()); } } if(StringUtils.isEmpty(id)){ log.info("活动或评论发送消息到es未传ID"); } contentSendMsgFactory.send(Long.valueOf(id),code); } catch (Throwable throwable) { log.error("统计社区用户失败{}",throwable); } return result; } @Autowired public void setContentSendMsgFactory(ContentSendMsgFactory contentSendMsgFactory) { this.contentSendMsgFactory = contentSendMsgFactory; } }
Around
@Around("activitySendMessage()&&@annotation(communityOperation)") public Object beforeRequestIdVerify(ProceedingJoinPoint joinPoint, CommunityOperation communityOperation) { Object result = null; try { result = joinPoint.proceed(); JSONObject jsonObject=JSONObject.parseObject(JSONObject.toJSONString(result)); if(jsonObject.getIntValue("code")== DefaultHttpResultStatus.SUCCESS.getCode()){ JSONObject params=JSONObject.parseObject(JSONObject.toJSONString(joinPoint.getArgs()[0])); Integer code=communityOperation.type().getCode(); if(communityOperation.type().getCode()==null){ code=params.getInteger(communityOperation.typeName()); } if(StringUtils.isEmpty(params.getString(communityOperation.id()))){ log.info("活动或评论发送消息到es未传ID"); } contentSendMsgFactory.send(params.getLong(communityOperation.id()),code); } } catch (Throwable throwable) { log.error("统计社区用户失败{}",throwable); } return result; }
@Before
用于打印请求类名、方法名、请求参数
@Before(value = "pointcutController()") public void before(JoinPoint joinPoint) { String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); List<Object> logArgs = streamOf(args) .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse))&& (arg instanceof MultipartHttpServletRequest)) .collect(Collectors.toList()); String argsJson = JSON.toJSONString(logArgs); String beforeLog = String.format("开始调用%s.%s,参数为:%s", className, methodName, argsJson); log.info(beforeLog); }
使用
@CommunityOperation(id="id",type= ContentTypeEnum.ACTIVITY) @PostMapping("/v1/publish") public HttpResult<Boolean> publish(@NotNull @RequestBody final ActivityRequestBean activityRequestBean) { return DefaultHttpResultFactory.fail("发布/取消失败。", Boolean.FALSE); }
-
SpringBoot基于自定义注解实现切面编程
2021-03-17 21:17:171、相关依赖包org.springframework.bootspring-boot-starter-aoporg.aspectjaspectjrt1.8.62、定义切面类package com.bz.aspect;import com.bz.service.SysLogOperationService;import org.aspectj.lang.... -
Java自定义切面缓存注解如此简单(Redis + SpringAop)
2021-11-17 11:45:07自定义缓存切面注解 1:展示效果 1.1: 成功保存到redis效果 第一次Redis没有值,所以保存查询了数据库。 1.2:第二次请求 2.1:前置条件 技术栈需要会简单的redis存、取、删和SpringAop即可 2.2: 安装redis ... -
Spring中切面捕获自定义异常
2018-04-24 22:07:35Spring中,使用切面全局捕获异常的同时,进行自定义异常抛出捕获,方便代码书写。 -
SpringBoot学习笔记之自定义注解与aop切面
2021-03-17 21:16:57SpringBoot学习之自定义注解与aop切面的使用,通过使用自定义注解和aop切面来调用service层方法和参数等。一. 自定义注解类,我们先自定义一个@Action注解,代码如下。packagecom.casking.chcs.modules.test.service... -
【记】自定义切面导致的事务失效问题
2021-12-01 23:37:47自定义切面导致的事务失效问题 1、问题引出 在本地测试中,发现在一段被@Transaction注解标注的方法即使抛出了RunTimeException,数据库依然会有新的记录产生,也就是事务没有回滚,代码如下: 多次检查事务相关都... -
Spring自定义AOP切面
2021-03-23 19:38:38切面 切面需要实现PointcutAdvisor接口,包含切点和通知。 package com.morris.spring.aop; import org.aopalliance.aop.Advice; import org.springframework.aop.Pointcut; import org.springframework.aop.... -
springboot 自定义切面类
2021-07-23 15:59:54AOP(Aspect Oriented Programing):面向切面编程,将通用的逻辑从业务逻辑中分离出来。AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横... -
Java-Spring 自定义注解和切面的使用
2018-08-27 21:27:52java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。包含在 java.lang.annotation 包中。 1:写元... -
java通过自定义注解实现切面记录操作日志
2020-05-21 10:48:58java通过自定义注解实现切面记录操作日志自定义注解java.lang.annotation为开发者提供的元注解日志自定义注解实例日志切面实现在业务逻辑中使用自定义注解记录操作日志 自定义注解 java.lang.annotation为开发者提供... -
【spring】自定义AOP切面
2022-04-06 11:21:33在Spring中,实现AOP增强不仅可以使用@Aspect注解来实现,还可以通过自定义切面来实现。 下面来看看怎么自定义切面。 切面 切面需要实现PointcutAdvisor接口,一个切面必须包含切点和通知。 package ... -
自定义注解实现自定义切面类
2020-06-09 11:29:02自定义注解的方式实现自定义切面类 参考 参考文献: 源代码及文章:https://www.cnblogs.com/hhhshct/p/8428045.html 自定义注解参考文章:... -
应用市场中Java拦截器和切面的使用实例详解
2020-08-28 06:10:15主要介绍了应用市场中Java拦截器和切面的使用实例详解,具有一定借鉴价值,需要的朋友可以参考下 -
自定义切面注解没生效的原因
2021-06-01 10:47:01博主的问题是 用this无法生效切面 public class ServiceImpl implements Service { @Override public T getAssetDetail() { xxxxxx; } @Override @TranslateRemoteField public T ... -
Spring 如何自定义切面注解
2021-04-12 13:34:57二、对自定义切面进行声明,在自定义切面类中对注解切入时执行的方法进行业务编写; 三、在需要使用注解切入的地方进行注解声明使用; 具体的操作说明如下: 1、原测试工程很简单,一个pojo实体类,一个dao类,... -
多个切面(事务切面+自定义切面)对同一个方法进行拦截,查询不到事务保存的数据问题解决
2022-01-04 15:05:35考虑到多个线程并发访问的情况,所以需要通过分布式锁进行实现,同时新增是持久化到数据库中 伪代码实现如下: @Component public class A { @Autowired private A current; public B methodA() { // 查询... -
自定义切面基于注解@Aspect及语法详解
2020-10-20 16:59:28自定义切面基于注解@Aspect及语法详解 前言 语法详解 @Pointcut 切面可捕获的连接点种类 切入点指示符 AspectJ类型匹配的通配符 示例 5种通知类型 代码示例 前言 AOP 把软件的功能模块分为两个部分:核心关注点和横... -
spring自定义切面执行顺序的方法
2019-10-24 22:29:22文章介绍了在使用spring框架编写切面的时候,如何控制切面的执行顺序和切面方法的执行顺序。 -
Java 利用AOP切面实现自定义注解示例
2019-07-22 16:30:21* AOP为Aspect Oriented Programming的缩写,意为:面向切面编程 * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构 * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到... -
Spring切面中实现自定义注解
2019-06-06 11:23:161.首先写出一个自定义注解。 package com.salong.aspect.test; import java.lang.annotation.*; @Target(ElementType.METHOD) @Documented @Retention(RetentionPolicy.RUNTIME) public @interface Login { ... -
自定义切面会吃掉异常,导致事务不生效的问题。
2018-06-12 10:56:40对于@AfterThrowing和@Around,我们可以再切面中捕获异常,处理异常。 我们也知道,我们对一个方法添加事务,那么当此方法抛出异常后,事务会捕获异常,自动执行混滚。 那么,如果添加事务的方法就是我们说的那个... -
通过@Aspect切面自定义注解
2021-07-19 18:26:21一种通过切面编程来自定义注解,以下代码demo是通过自定义注解对加密参数进行验证的过程,不用关心代码的业务过程,直接看通过@Aspect是如何自定义注解的,有了以下代码,springboot工程中的主类还需要加 ... -
自定义注解+切面处理+全局异常处理
2022-03-01 15:08:001、注解方法 /** * 自定义注解签名参数验证 * xuxx */ @Retention(RetentionPolicy.RUNTIME) ...2、切面处理类 import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Asp -
Springboot Aop 自定义注解、切面
2020-09-02 13:50:25Springboot 自定义注解、切面 1、创建springboot工程,引入依赖 本次任务实例主要引入以下两个依赖即可。 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> ...