springboot Aop配置,并使用自定义注解annotation,并且拦截service层
前言
用Spring Boot的AOP来简化处理自定义注解,并将通过实现一个简单的方法执行判断节点是否开始的状态示列源码。
AOP概念
面向侧面的程序设计(aspect-oriented programming,AOP,又译作面向方面的程序设计、观点导向编程、剖面导向程序设计)是计算机科学中的一个术语,指一种程序设计范型。该范型以一种称为侧面(aspect,又译作方面)的语言构造为基础,侧面是一种新的模块化机制,用来描述分散在对象、类或函数中的横切关注点(crosscutting concern)。
Spring Boot的AOP环境准备
在pom.xml中引入相应的依赖模块
<!-- AOP依赖模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
先建一个简单地建一个自定义注解类

一个简单地自定义注解类就生成了:
package com.common.annotation; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; /**
* 自定义注解
* @Description 自定义注解@HAStatusCheck 拦截service层 HAStatusCheckService
* @Author Justin zeng
* @Date 2019-04-19
* @version 1.0
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface HAStatusCheck {
//自定义的方法描述信息
String description() default "";
}
在建一个切点类实现你的要处理的事情
package com.common.aop; import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.util.ArrayList; import javax.annotation.Resource; 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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.aspectj.lang.reflect.MethodSignature; import com.common.annotation.HAStatusCheck;
import com.common.enums.ha.ServerPort;
import com.common.enums.ha.ServerType;
import com.common.ha.HAStatusCheckService;
/**
* 切点类
* @Description AOP拦截判断 HA节点是否开启状态方法Service层
* @Author Justin zeng
* @Date 2019-04-19
* @version 1.0
*/
@Aspect
@Component
public class HAStatusCheckAop {
//注入Service
@Resource
private HAStatusCheckService hAStatusCheckService;
private static final Logger LOG = LoggerFactory.getLogger(HAStatusCheckAop.class); //Service层切点 自定义的注解类路径
@Pointcut("@annotation(com.common.annotation.HAStatusCheck)")
public void servicePointCut() {} Object proceed=null;
@Around("servicePointCut()")
public void logAroundService(ProceedingJoinPoint jointPoint) throws Throwable {
LOG.info("------判断节点开始------");
ArrayList<String> list = new ArrayList<String>();
list.add("192.168.1.5");
if (!hAStatusCheckService.isActAsActiveNode(list, ServerPort.BILLING_HANDLER, ServerType.BILLING_HANDLER)) {
LOG.info("------访问请求不合法!------");
return;
//强制退出
//System.exit(0);
}else {
LOG.info("------判断注解开始------");
//获得当前访问的class
Class<?> className = jointPoint.getTarget().getClass();
//获得访问的方法名
String methodName = jointPoint.getSignature().getName();
//得到方法的参数的类型
Class[] argClass = ((MethodSignature) jointPoint.getSignature()).getParameterTypes();
try {
// 得到访问的方法对象
Method method = className.getDeclaredMethod(methodName, argClass);
// 判断是否存在@HAStatusCheck注解
if (method.isAnnotationPresent(HAStatusCheck.class)) {
HAStatusCheck annotation = method.getAnnotation(HAStatusCheck.class);
annotation.description();
LOG.info("当前目标执行方法:"+methodName+"执行开始");
//执行当前目标中的方法
proceed = jointPoint.proceed();
LOG.info("当前目标class路径:"+className);
LOG.info("当前目标执行方法名:" + methodName);
LOG.info("当前目标执行方法的参数类型:" + argClass);
LOG.info("当前目标方法执行的结果:" + proceed);
LOG.info("当前目标执行方法:"+methodName+"执行结束");
}
} catch (Exception e) {
LOG.error("不存在@HAStatusCheck注解",e);
}
}
} /**
* 获取注解中对方法的描述信息 用于service层注解
*
* @param joinPoint 切点
* @return 方法描述
* @throws Exception
*/
public static String getServiceMthodDescription(JoinPoint joinPoint)
throws Exception {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
String description = "";
for (Method method : methods) {
if (method.getName().equals(methodName)) {
Class[] clazzs = method.getParameterTypes();
if (clazzs.length == arguments.length) {
description = method.getAnnotation(HAStatusCheck. class).description();
LOG.info("======"+description+"======");
break;
}
}
}
return description;
} }
最后
在你需要的判断预处理的地方加上自定义的注解 @HAStatusCheck
package com.job; import com.annotation.HAStatusCheck; import lombok.extern.slf4j.Slf4j; @Slf4j
public class TestJob {
//这就是上面自定义的注解
@HAStatusCheck
public void job() throws Exception {
System.out.println("TestJob job run ....");
}
}
这样自定义注解拦截service层开发就结束了,需要的可以试试吧,希望能帮到大家。
springboot Aop配置,并使用自定义注解annotation,并且拦截service层的更多相关文章
- springBoot AOP环绕增强、自定义注解、log4j2、MDC
(一)log4j2 maven配置 <dependency> <groupId>org.springframework.boot</groupId> <art ...
- 使用自定义注解和springAOP捕获Service层异常,并处理自定义异常
一 自定义异常 /** * 自定义参数为null异常 */ public class NoParamsException extends Exception { //用详细信息指定一个异常 publi ...
- spring自定义注解实现登陆拦截器
1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...
- 2.基于AOP自定义注解Annotation的实现
上一篇中分析了AOP的实现原理, 总结为: 判断对象是否需要被代理?@Aspect注解的实现是根据切入点表达式 代理之后需要做什么,就是那些通知,本质上是实现了MethodInterceptor的拦截 ...
- 【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截
一.前言 上一篇博客向大家介绍了Aop的概念,对切面=切点+通知 .连接点.织入.目标对象.代理(jdk动态代理和CGLIB代理)有所了解了.理论很强,实用就在这篇博客介绍. 这篇博客中,小编向大家介 ...
- AOP通过反射获取自定义注解
自定义注解: @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component publ ...
- 一小时搞明白自定义注解(Annotation)
原文链接:http://blog.csdn.net/u013045971/article/details/53433874 什么是注解 Annotation(注解)就是Java提供了一种元程序中的元素 ...
- 自定义注解--Annotation
Annotation 概念:注解 原理 是一种接口,通过反射机制中的相关API来访问annotation信息 常见的标准Annotation @Override 方法重写 @Deprecated ...
- Spring AOP基础概念及自定义注解式AOP初体验
对AOP的理解开始是抽象的,看到切点的匹配方式其实与正则表达式性质大致一样就基本了解AOP是基本是个什么作用了.只是整个概念更抽象,需要具化理解.下图列表是AOP相关概念解释,可能也比较抽象^_^ 比 ...
随机推荐
- 洛谷P3709 大爷的字符串题(莫队)
题目背景 在那遥远的西南有一所学校 /*被和谐部分*/ 然后去参加该省省选虐场 然后某蒟蒻不会做,所以也出了一个字符串题: 题目描述 给你一个字符串a,每次询问一段区间的贡献 贡献定义: 每次从这个区 ...
- loj#6229 这是一道简单的数学题
\(\color{#0066ff}{ 题目描述 }\) 这是一道非常简单的数学题. 最近 LzyRapxLzyRapx 正在看 mathematics for computer science 这本书 ...
- luogu1447 [NOI2010]能量采集 莫比乌斯反演
link 冬令营考炸了,我这个菜鸡只好颓废数学题了 NOI2010能量采集 由题意可以写出式子: \(\sum_{i=1}^n\sum_{j=1}^m(2\gcd(i,j)-1)\) \(=2\sum ...
- 洛谷 P1003 铺地毯
嗯.... 一道比较水的模拟题.. 刚拿到题的时候被它的数据范围吓到了,二维数组不可能开那么大啊,可是一边做发现测试数据太水 ... 先看一下题吧... 题目描述 为了准备一个独特的颁奖典礼,组织者在 ...
- Unity组件
在学习C++的时候,对于面对对象有点了解.然后也使用过一段时间的Unity,用起来还是觉得,怎么这么好用.耦合性极低.当时不知道这是基于组件编程.所以现在来学习下基于组件的知识,并比较下基于组件和基于 ...
- 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_new新建对象
CLR使用 new 操作符来创建新对象,例如:Employee e=new Employee("Param1"); 以下是 new 操作符所做的事情. 它计算类型及其所有基类型 ...
- [例] 用MappedByteBuffer更新文件内容
import java.io.IOException; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; impor ...
- form组件之modelForm
modelForm的使用及参数设置 从modelForm这个名字就能看出来,这个form是和模型类model有知己诶关联的,还是以数和出版社的模型来说明: models.py(模型) from dja ...
- python3 关键字和可变参数笔记
"""普及一下字典的知识""" # dict = {'Name': 'Runoob', 'Age': 7, 'Class': 'First' ...
- python 安装 第三方包
########1 (python 虚拟环境(如pycharm 中的 project )是一个独立的环境,所以也要重新安装一次第三方包) 上官网搜索 包 https://pypi.org/projec ...