前言

用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层的更多相关文章

  1. springBoot AOP环绕增强、自定义注解、log4j2、MDC

    (一)log4j2 maven配置 <dependency> <groupId>org.springframework.boot</groupId> <art ...

  2. 使用自定义注解和springAOP捕获Service层异常,并处理自定义异常

    一 自定义异常 /** * 自定义参数为null异常 */ public class NoParamsException extends Exception { //用详细信息指定一个异常 publi ...

  3. spring自定义注解实现登陆拦截器

    1.spring自定义注解实现登陆拦截器 原理:定义一个注解和一个拦截器,拦截器拦截所有方法请求,判断该方法有没有该注解.没有,放行:有,要进行验证.从而实现方法加注解就需要验证是否登陆. 2.自定义 ...

  4. 2.基于AOP自定义注解Annotation的实现

    上一篇中分析了AOP的实现原理, 总结为: 判断对象是否需要被代理?@Aspect注解的实现是根据切入点表达式 代理之后需要做什么,就是那些通知,本质上是实现了MethodInterceptor的拦截 ...

  5. 【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截

    一.前言 上一篇博客向大家介绍了Aop的概念,对切面=切点+通知 .连接点.织入.目标对象.代理(jdk动态代理和CGLIB代理)有所了解了.理论很强,实用就在这篇博客介绍. 这篇博客中,小编向大家介 ...

  6. AOP通过反射获取自定义注解

    自定义注解: @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component publ ...

  7. 一小时搞明白自定义注解(Annotation)

    原文链接:http://blog.csdn.net/u013045971/article/details/53433874 什么是注解 Annotation(注解)就是Java提供了一种元程序中的元素 ...

  8. 自定义注解--Annotation

    Annotation 概念:注解 原理 是一种接口,通过反射机制中的相关API来访问annotation信息 常见的标准Annotation @Override   方法重写 @Deprecated  ...

  9. Spring AOP基础概念及自定义注解式AOP初体验

    对AOP的理解开始是抽象的,看到切点的匹配方式其实与正则表达式性质大致一样就基本了解AOP是基本是个什么作用了.只是整个概念更抽象,需要具化理解.下图列表是AOP相关概念解释,可能也比较抽象^_^ 比 ...

随机推荐

  1. A4纸和一寸照在屏幕的尺寸计算

    参考地址 https://www.cnblogs.com/lenther2002/p/5105126.html A4纸 A4纸的尺寸是210mm×297mm. 分辨率是72像素/英寸时,A4纸的尺寸的 ...

  2. uoj#450. 【集训队作业2018】复读机(单位根反演)

    题面 传送门 题解 我的生成函数和单位根反演的芝士都一塌糊涂啊-- \(d=1\),答案就是\(k^n\)(因为这里\(k\)个复读机互不相同,就是说有标号) \(d=2\),我们考虑复读机的生成函数 ...

  3. 使用Tensorflow object detection API——环境搭建与测试

    [软件环境搭建] 操作系统:windows 10 64位 内存:8G CPU:I7-6700 Tensorflow: 1.4 Python:3.5 Anaconda3 (64-bit) 以上环境搭建请 ...

  4. Qt 学习之路 2(8):添加动作

    Home / Qt 学习之路 2 / Qt 学习之路 2(8):添加动作       [在WINDOWS10 QTCREATOR MENU添加无效]   Qt 学习之路 2(8):添加动作  豆子   ...

  5. [Android]Android开发艺术探索第1章笔记

    1.1 Activity 的生命周期全面分析 1.1.1 典型情况下的生命周期分析 onPause: 正在停止,正常情况下紧接着 onStop 就会被调用,然后新的 Activity 执行 onRes ...

  6. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  7. Django之auth模块(用户认证)登陆组件

    auth模块简介 auth模块是对登录认证方法的一种封装,之前我们获取用户输入的用户名及密码后需要自己从user表里查询有没有用户名和密码符合的对象, 而有了auth模块之后就可以很轻松的去验证用户的 ...

  8. SQL Connect By 的例子

    看到一个较为通俗易懂的connect by的例子,是百度知道的答案,稍微整理了一下.我自己这样理解:connect by prior "id" = "p_id" ...

  9. Ubuntu14.04配置python接口,测试的小问题

    当遇到“ImportError:No module named google.protobuf.internal”(import enum_type_wrapper)的问题时候 solution: P ...

  10. 2.1 Rust概念

    标识符 The first character is a letter.The remaining characters are alphanumeric or _.或The first charac ...