1. 程式人生 > >java/springboot自定義註解實現AOP

java/springboot自定義註解實現AOP

 

java註解

即是註釋了,百度解釋:也叫元資料。一種程式碼級別的說明。 個人理解:就是內容可以被程式碼理解的註釋,一般是一個類。

元資料

也叫元註解,是放在被定義的一個註解類的前面 ,是對註解一種限制。

談下這兩個: @Retention 和 @Target  

@Retention :用來說明該註解類的生命週期。它有以下三個引數:

RetentionPolicy.SOURCE  : 註解只保留在原始檔中

RetentionPolicy.CLASS  : 註解保留在class檔案中,在載入到JVM虛擬機器時丟棄

RetentionPolicy.RUNTIME  : 註解保留在程式執行期間,此時可以通過反射獲得定義在某個類上的所有註解。

@Target :  用來說明該註解可以被宣告在那些元素之前。

ElementType.TYPE:說明該註解只能被宣告在一個類前。

ElementType.FIELD:說明該註解只能被宣告在一個類的欄位前。

ElementType.METHOD:說明該註解只能被宣告在一個類的方法前。

ElementType.PARAMETER:說明該註解只能被宣告在一個方法引數前。

ElementType.CONSTRUCTOR:說明該註解只能宣告在一個類的構造方法前。

ElementType.LOCAL_VARIABLE:說明該註解只能宣告在一個區域性變數前。

ElementType.ANNOTATION_TYPE:說明該註解只能宣告在一個註解型別前。

ElementType.PACKAGE:說明該註解只能宣告在一個包名前。

 

實現自定義註解AOP:

LogAnnotation.java

package com.pupeiyuan.aop;

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;

import javax.persistence.Inheritance; @Documented//說明該註解將被包含在javadoc中 @Retention(RetentionPolicy.RUNTIME)// 註解會在class位元組碼檔案中存在,在執行時可以通過反射獲取到 @Target(ElementType.METHOD) @Inheritance//說明子類可以繼承父類中的該註解 public @interface LogAnnotation { String value() default "-----AOP攔截執行完畢!----"; }

 

WebLogAspect.java

package com.pupeiyuan.aop;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
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.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

@Aspect
@Component
public class WebLogAspect {

    protected static final Logger logger = Logger.getLogger(WebLogAspect.class);
    
    //定義一個切入點
    @Pointcut("@annotation(com.pupeiyuan.aop.LogAnnotation)")
    public void annotationPointCut(){
        
    }
    @Before("annotationPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        
        MethodSignature methodSignature = (MethodSignature)joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
        // 記錄請求到達時間
         //接收到請求,記錄請求內容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        // 記錄下請求內容
        logger.info("URI : " + request.getRequestURI());
        logger.info("URL : " + request.getRequestURL());
        logger.info("HTTP_METHOD : " + request.getMethod());
        logger.info("IP : " + request.getRemoteAddr());
        logger.info(annotation.value());
    }
}

 

controller

package com.pupeiyuan.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.github.pagehelper.PageHelper;
import com.pupeiyuan.aop.LogAnnotation;
import com.pupeiyuan.bean.NhReportStatusHistory;
import com.pupeiyuan.common.controller.BaseController;
import com.pupeiyuan.core.DataSourceKey;
import com.pupeiyuan.core.DynamicDataSourceContextHolder;
import com.pupeiyuan.services.NhReportService;
/**
 * @author pypua
 * @date 2018年8月30日 上午9:21:20
 * 
 */
@Controller
@RequestMapping("burket")
@Scope("prototype")
public class BurketController extends BaseController {
    
    //services層注入
    @Autowired NhReportService nhReportService;
    @LogAnnotation
    @RequestMapping(value = "/burketList", method = {RequestMethod.GET,RequestMethod.POST})
    public ModelAndView burketList(HttpServletRequest request,
            HttpServletResponse response
            ) throws Exception {
        System.out.println("hello,springboot");
       //引數容器
        Map<String, Object> params = new HashMap<String, Object>();
        PageHelper.startPage(1, 2);
        DynamicDataSourceContextHolder.set(DataSourceKey.DB_SLAVE1);
        List<NhReportStatusHistory> findList = nhReportService.findList(params);
        ModelAndView modelAndView = new ModelAndView(); 
        modelAndView.setViewName("burketList");
        modelAndView.addObject("list", findList);
        return modelAndView;
    }
    
}

 

效果

spring攔截器----方法執行之前---------
2018-12-07 16:48:53.769 INFO 92292 --- [nio-8082-exec-4] com.pupeiyuan.aop.WebLogAspect : URI : /burket/burketList
2018-12-07 16:48:53.778 INFO 92292 --- [nio-8082-exec-4] com.pupeiyuan.aop.WebLogAspect : URL : http://localhost:8082/burket/burketList
2018-12-07 16:48:53.778 INFO 92292 --- [nio-8082-exec-4] com.pupeiyuan.aop.WebLogAspect : HTTP_METHOD : GET
2018-12-07 16:48:53.778 INFO 92292 --- [nio-8082-exec-4] com.pupeiyuan.aop.WebLogAspect : IP : 0:0:0:0:0:0:0:1
2018-12-07 16:48:53.778 INFO 92292 --- [nio-8082-exec-4] com.pupeiyuan.aop.WebLogAspect : -----AOP攔截執行完畢!----
hello,springboot
2018-12-07 16:48:53.788 INFO 92292 --- [nio-8082-exec-4] c.p.core.DynamicRoutingDataSource : 當前資料來源:{}DB_SLAVE1