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() </span><span style="color: rgba(0, 0, 255, 1)">default</span> "-----AOP拦截执行完毕!----"<span style="color: rgba(0, 0, 0, 1)">;

}

 

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 {

</span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> Logger logger = Logger.getLogger(WebLogAspect.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">定义一个切入点</span>
@Pointcut("@annotation(com.pupeiyuan.aop.LogAnnotation)"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> annotationPointCut(){
    
}
@Before(</span>"annotationPointCut()"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> doBefore(JoinPoint joinPoint) {
    
    MethodSignature methodSignature </span>=<span style="color: rgba(0, 0, 0, 1)"> (MethodSignature)joinPoint.getSignature();
    Method method </span>=<span style="color: rgba(0, 0, 0, 1)"> methodSignature.getMethod();
    LogAnnotation annotation </span>= method.getAnnotation(LogAnnotation.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 记录请求到达时间
     </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接收到请求,记录请求内容</span>
    ServletRequestAttributes attributes =<span style="color: rgba(0, 0, 0, 1)"> (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request </span>=<span style="color: rgba(0, 0, 0, 1)"> attributes.getRequest();

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 记录下请求内容</span>
    logger.info("URI : " +<span style="color: rgba(0, 0, 0, 1)"> request.getRequestURI());
    logger.info(</span>"URL : " +<span style="color: rgba(0, 0, 0, 1)"> request.getRequestURL());
    logger.info(</span>"HTTP_METHOD : " +<span style="color: rgba(0, 0, 0, 1)"> request.getMethod());
    logger.info(</span>"IP : " +<span style="color: rgba(0, 0, 0, 1)"> 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 {

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">services层注入</span>

@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