SpringBoot 集成Aop 完成自定义注解功能 前提是需要掌握一定的Spring Aop知识
第一步:引入jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
第二步: 开启自动代理功能@EnableAspectJAutoProxy
package com.zhangheng;
import java.util.Properties;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.github.pagehelper.PageHelper;
/**
* 程序启动入口
*
* @author zhangh
* @date 2018年4月26日上午9:16:27
*/
@SpringBootApplication
@EnableAspectJAutoProxy
@MapperScan("com.zhangheng.dao")
public class Application {
/**
* @author zhangh
* @date 2018年4月28日下午5:18:38
* @param args
*/
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
// 下面的代码可以自定义banner 还可以控制banner的显示方式(log console off)
// SpringApplication app = new SpringApplication(Application.class);
// app.setBannerMode(Banner.Mode.OFF);
// app.run(args);
}
}
第三步: 编写自定义注解以及切面类
package com.zhangheng.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;
/**
* 校验参数
*
* @author zhangh
* @date 2018年4月26日上午9:37:58
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckParam {
}
package com.zhangheng.annotation;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import com.zhangheng.common.ResultEnum;
import com.zhangheng.exception.MyException;
import com.zhangheng.util.AnnotationUtil;
/**
* 自定义校验参数切面
*
* @author zhangh
* @date 2018年4月26日上午10:03:32
*/
@Aspect
@Component
@Order(1)
public class CheckParamAspect {
private static Logger logger = Logger.getLogger(CheckParamAspect.class);
@Pointcut("@annotation(com.zhangheng.annotation.CheckParam)")
public void pointCut() {}
/**
* 切面前置处理
*
* @param joinPoint
*/
@Before("pointCut()")
public void before(JoinPoint joinPoint) {
MethodSignature sign = (MethodSignature) joinPoint.getSignature();
logger.info("打印:" + sign.getDeclaringTypeName() + " 前置日志");
}
/**
* 切面回环处理 这个方法里不允许出现try catch 异常捕获 必须要往外抛
*
* @param proceedingJoinPoint
* @return
* @throws Throwable
* @author zhangh
*/
@Around("pointCut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object[] params = proceedingJoinPoint.getArgs();
boolean hasAuthor = params != null && params.length > 0 ? true : false;
if (hasAuthor && !params[0].toString().equals("-1")) {// 模拟校验参数
return proceedingJoinPoint.proceed();
} else {
logger.info("很抱歉 方法" + AnnotationUtil.getClassName(proceedingJoinPoint) + "."
+ AnnotationUtil.getMethodName(proceedingJoinPoint) + "参数校验失败");
throw new MyException(ResultEnum.PARAM_ERROR);
}
}
/**
* 切面后置处理
*
* @param joinPoint
*/
@After("pointCut()")
public void after(JoinPoint joinPoint) {
logger.info("调用aspect 方法结束");
}
}
第四步:编写统一异常处理
package com.zhangheng.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.zhangheng.common.ResultEnum;
import com.zhangheng.common.ResultInfo;
import com.zhangheng.util.ResultUtil;
@ControllerAdvice
public class MyExceptionHandler {
/**
* 全局异常处理
*
* @param e
* @return
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResultInfo<Object> handle(Exception e) {
if (e instanceof MyException) {
return ResultUtil.error(((MyException) e).getCode(), e.getMessage());
}else {
//String errorInfo = e.getCause().toString().substring(e.getCause().toString().lastIndexOf(":") + 1);
return ResultUtil.error(ResultEnum.UNKOWN_ERROR,e.getMessage());
}
}
/**
* MyException 异常处理
*
* @param e
* @return
*/
@ExceptionHandler(value = MyException.class)
@ResponseBody
public ResultInfo<Object> MyExceptionHandle(MyException e) {
if (e instanceof MyException) {
return ResultUtil.error(((MyException) e).getCode(), e.getMessage());
} else {
return ResultUtil.error(ResultEnum.UNKOWN_ERROR,e.getMessage());
}
}
}
package com.zhangheng.exception;
import com.zhangheng.common.ResultEnum;
public class MyException extends RuntimeException {
/**
*
*/
private static final long serialVersionUID = -5126369846766704829L;
private Integer code;
public MyException(ResultEnum resultEnum) {
super(resultEnum.getMsg());
this.code = resultEnum.getCode();
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
一些辅助工具类
package com.zhangheng.util;
import com.zhangheng.common.ResultEnum;
import com.zhangheng.common.ResultInfo;
/**
* 接口统一返回标准数据格式
* @author zhangh
* @date 2018年4月27日上午9:13:36
*/
public class ResultUtil {
/**
* 调用成功
* @param obj 返回的数据
* @return
*/
public static ResultInfo<Object> success(ResultEnum resultEnum,Object obj) {
return new ResultInfo<Object>(true, resultEnum.getCode(), resultEnum.getMsg(), obj);
}
/**
* 调用成功 不需要返回数据 只返回状态
* @return
*/
public static ResultInfo<Object> success(ResultEnum resultEnum) {
return new ResultInfo<Object>(true, resultEnum.getCode(), resultEnum.getMsg(), null);
}
/**
* 调用失败
* @param code 错误码
* @param msg 错误信息
* @return
*/
public static ResultInfo<Object> error(Integer code, String msg) {
return new ResultInfo<Object>(false, code, msg, null);
}
/**
* 从先定义好的枚举类中返回接口信息
* @param resultEnum
* @return
*/
public static ResultInfo<Object> error(ResultEnum resultEnum) {
return new ResultInfo<Object>(false, resultEnum.getCode(), resultEnum.getMsg(), null);
}
/**
* 重写之前已经实例化的枚举信息 不懂的别随意用
* @author zhangh
* @date 2018/4/27 10:08:22
* @param resultEnum
* @return
*/
public static ResultInfo<Object> error(ResultEnum resultEnum,String msg) {
return new ResultInfo<Object>(false, resultEnum.getCode(), msg, null);
}
}
package com.zhangheng.common;
/**
* 封装接口返回状态结果集
*
* @author zhangh
* @date 2018年4月26日下午2:34:37
*/
public enum ResultEnum {
SUCCESS(1, "成功"),
PARAM_ERROR(-1, "参数异常"),
AUTHORIZATION_ERROR(-2, "对不起,您的权限不够"),
DADABASE_ERROR(-3,"网络超时"),
UNKOWN_ERROR(-99, "未知错误");//这里的信息以程序捕获的具体异常信息为主
private Integer code;
private String msg;
ResultEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
以上就是SpringBoot 集成自定义注解的全部步骤了,如有不懂的请留言。