SpringBoot 整合AOP 自定義註解
阿新 • • 發佈:2019-02-01
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 整合自定義註解的全部步驟了,如有不懂的請留言。