本文抛砖引玉,并没有详细的介绍更全面的内容,通过一个例子让初次使用的人能够快速入门,简单的介绍一下。

第一‍‍,注解‍‍‍‍:‍

  1. @Before – 目标方法执行前执行

  2. @After – 目标方法执行后执行

  3. @AfterReturning – 目标方法返回后执行,如果发生异常不执行

  4. @AfterThrowing – 异常时执行

  5. @Around – 在执行上面其他操作的同时也执行这个方法

第二,SpringMVC如果要使用AOP注解,必须将

<aop:aspectj-autoproxy proxy-target-class="true"/>

放在spring-servlet.xml(配置MVC的XML)中

第三,execution表达式请参考Spring官网http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

代码下载:http://pan.baidu.com/s/1gdeopW3

项目截图

首先是Maven依赖

<properties>
<springframework>4.0.5.RELEASE</springframework>
<aspectj>1.8.5</aspectj>
<servlet>3.1.0</servlet>
</properties>
<dependencies>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet}</version>
<scope>compile</scope>
</dependency>
<!-- Spring web mvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework}</version>
</dependency>
<!-- Spring AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${springframework}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj}</version>
</dependency>
</dependencies>

spring-context.xml配置,基本无内容

<!-- 配置扫描路径 -->
<context:component-scan base-package="org.xdemo.example.springaop">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

spring-mvc.xml配置

<!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 启用MVC注解 -->
<mvc:annotation-driven /> <!-- 指定Sping组件扫描的基本包路径 -->
<context:component-scan base-package="org.xdemo.example.springaop">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

Web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
<display-name>Archetype Created Web Application</display-name>
<!-- WebAppRootKey -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>org.xdemo.example.springaop</param-value>
</context-param> <!-- Spring Context -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- SpringMVC -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>

注解Log

package org.xdemo.example.springaop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD })
public @interface Log {
String name() default "";
}

日志AOP,写法一LogAop_1

package org.xdemo.example.springaop.aop;

import java.lang.reflect.Method;
import java.util.UUID; 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.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.xdemo.example.springaop.annotation.Log; @Aspect
@Component
public class LogAop_1 { ThreadLocal<Long> time=new ThreadLocal<Long>();
ThreadLocal<String> tag=new ThreadLocal<String>(); /**
 * 在所有标注@Log的地方切入
 * @param joinPoint
 */
@Before("@annotation(org.xdemo.example.springaop.annotation.Log)")
public void beforeExec(JoinPoint joinPoint){ time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString()); info(joinPoint); MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
} @After("@annotation(org.xdemo.example.springaop.annotation.Log)")
public void afterExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
} @Around("@annotation(org.xdemo.example.springaop.annotation.Log)")
public void aroundExec(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("我是Around,来打酱油的");
pjp.proceed();
} private void info(JoinPoint joinPoint){
System.out.println("--------------------------------------------------");
System.out.println("King:\t"+joinPoint.getKind());
System.out.println("Target:\t"+joinPoint.getTarget().toString());
Object[] os=joinPoint.getArgs();
System.out.println("Args:");
for(int i=0;i<os.length;i++){
System.out.println("\t==>参数["+i+"]:\t"+os[i].toString());
}
System.out.println("Signature:\t"+joinPoint.getSignature());
System.out.println("SourceLocation:\t"+joinPoint.getSourceLocation());
System.out.println("StaticPart:\t"+joinPoint.getStaticPart());
System.out.println("--------------------------------------------------");
} }

日志AOP,写法二LogAop_2

package org.xdemo.example.springaop.aop;

import java.lang.reflect.Method;
import java.util.UUID; 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.stereotype.Component;
import org.xdemo.example.springaop.annotation.Log; @Aspect
@Component
public class LogAop_2 { ThreadLocal<Long> time=new ThreadLocal<Long>();
ThreadLocal<String> tag=new ThreadLocal<String>(); @Pointcut("@annotation(org.xdemo.example.springaop.annotation.Log)")
public void log(){
System.out.println("我是一个切入点");
} /**
 * 在所有标注@Log的地方切入
 * @param joinPoint
 */
@Before("log()")
public void beforeExec(JoinPoint joinPoint){ time.set(System.currentTimeMillis());
tag.set(UUID.randomUUID().toString()); info(joinPoint); MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
} @After("log()")
public void afterExec(JoinPoint joinPoint){
MethodSignature ms=(MethodSignature) joinPoint.getSignature();
Method method=ms.getMethod();
System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
} @Around("log()")
public void aroundExec(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("我是Around,来打酱油的");
pjp.proceed();
} private void info(JoinPoint joinPoint){
System.out.println("--------------------------------------------------");
System.out.println("King:\t"+joinPoint.getKind());
System.out.println("Target:\t"+joinPoint.getTarget().toString());
Object[] os=joinPoint.getArgs();
System.out.println("Args:");
for(int i=0;i<os.length;i++){
System.out.println("\t==>参数["+i+"]:\t"+os[i].toString());
}
System.out.println("Signature:\t"+joinPoint.getSignature());
System.out.println("SourceLocation:\t"+joinPoint.getSourceLocation());
System.out.println("StaticPart:\t"+joinPoint.getStaticPart());
System.out.println("--------------------------------------------------");
} }

用到的一个用户类User

package org.xdemo.example.springaop.bean;

public class User {

	private String name;

	public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }

一个测试的Controller

package org.xdemo.example.springaop.controller;

import javax.annotation.Resource;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.xdemo.example.springaop.annotation.Log;
import org.xdemo.example.springaop.bean.User;
import org.xdemo.example.springaop.service.IUserService; @Controller
@RequestMapping("/aop")
public class SpringController { @Resource IUserService userService; @Log(name="您访问了aop1方法")
@ResponseBody
@RequestMapping(value="aop1")
public String aop1(){
return "AOP";
} @Log(name="您访问了aop2方法")
@ResponseBody
@RequestMapping(value="aop2")
public String aop2(String string) throws InterruptedException{
Thread.sleep(1000L);
User user=new User();
user.setName(string);
userService.save(user);
return string;
} }

一个测试的接口实现类(接口类略)

package org.xdemo.example.springaop.service;

import org.springframework.stereotype.Service;
import org.xdemo.example.springaop.annotation.Log;
import org.xdemo.example.springaop.bean.User; @Service
public class UserServiceImpl implements IUserService { @Log(name = "您访问了保存用户信息")
public void save(User user) {
System.out.println(user.getName());
} }

在地址栏输入地址测试http://localhost:8080/springaop/aop/aop2?string=sxxxxx

结果如下:

转载请注明来源:http://www.xdemo.org/springmvc-aop-annotation/ 

SpringMVC利用AOP实现自定义注解记录日志的更多相关文章

  1. 利用反射跟自定义注解拼接实体对象的查询SQL

    前言 项目中虽然有ORM映射框架来帮我们拼写SQL,简化开发过程,降低开发难度.但难免会出现需要自己拼写SQL的情况,这里分享一个利用反射跟自定义注解拼接实体对象的查询SQL的方法. 代码 自定义注解 ...

  2. spring AOP 和自定义注解进行身份验证

    一个SSH的项目(springmvc+hibernate),需要提供接口给app使用.首先考虑的就是权限问题,app要遵循极简模式,部分内容无需验证,用过滤器不能解决某些无需验证的方法 所以最终选择用 ...

  3. AOP 实现自定义注解

    1.自定义注解2.编写 AOP3.测试 1.自定义注解 package com.base.yun.spring.aop; import java.lang.annotation.Documented; ...

  4. SpringMVC拦截器+Spring自定义注解实现权限验证

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  5. springboot通过AOP和自定义注解实现权限校验

    自定义注解 PermissionCheck: package com.mgdd.sys.annotation; import java.lang.annotation.*; /** * @author ...

  6. 简单实现springmvc框架(servlet+自定义注解)

    个人水平比较菜,没有这么高的实力简单实现springmvc框架,我是看了一个老哥的博客,这老哥才是大神! 原文链接:https://www.cnblogs.com/xdp-gacl/p/4101727 ...

  7. Spring Boot系列——AOP配自定义注解的最佳实践

    AOP(Aspect Oriented Programming),即面向切面编程,是Spring框架的大杀器之一. 首先,我声明下,我不是来系统介绍什么是AOP,更不是照本宣科讲解什么是连接点.切面. ...

  8. 用AOP拦截自定义注解并获取注解属性与上下文参数(基于Springboot框架)

    目录 自定义注解 定义切面 获取上下文信息JoinPoint ProceedingJoinPoint 定义测试方法 测试结果 小结 AOP可以用于日志的设计,这样话就少不了要获取上下文的信息,博主在设 ...

  9. java 利用反射完成自定义注解

    元注解: 元注解的作用就是负责注解其他注解.Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明.Java5.0定义的元注解: 1.@ ...

随机推荐

  1. iText输出中文

    使用iTextAsian.jar中的字体 BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont ...

  2. Jmeter做HTTP接口测试

    接口测试概述:https://www.cnblogs.com/mawenqiangios/p/7886115.html Jmeter接口测试教程:https://www.cnblogs.com/hou ...

  3. JVM -- 虚拟机中的对象

    一.HotSpot虚拟机 它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机.我们大致知道虚拟机内存的概况,也许更想了解这些虚拟机内存的数据的其他细节,誓如它们是如 ...

  4. PAT(B) 1018 锤子剪刀布(C:20分,Java:18分)

    题目链接:1018 锤子剪刀布 分析 用一个二维数组保存两人所有回合的手势 甲乙的胜,平,负的次数刚好相反,用3个变量表示就可以 手势单独保存在signs[3]中,注意顺序.题目原文:如果解不唯一,则 ...

  5. 1187: 零起点学算法94——今年暑假不AC(Java)

    1187:零起点学算法94--今年暑假不AC Time Limit: 1 Sec Memory Limit: 32 MB 64bit IO Format: %lld Description " ...

  6. Image splicing forgery detection combining coarse to refined convolutional neural network and adaptive clustering

    粗到精的卷积神经网络与自适应聚类相结合的图像拼接篡改检测 研究方向:图像篡改检测 论文出处:ELSEVIER A类 学校:西安电子科技大学网络工程学院.重庆邮电大学计算机科学与技术学院 关键字:Spl ...

  7. IDEA GIT 忽略文件 最佳方式

    前言 转载一篇博客,简单,实用. 原文地址:intellij idea 忽略文件不提交 ps:下面均为转载博客的内容: 在intellij中忽略提交文件,分两种情况, 文件没有纳入版本管理 第一种,文 ...

  8. 设计模式(四)——代理模式(Proxy)

    代理模式的参与者有:一个约束.一个代理者.一个被代理者.一个调用者 代理模式的实现很简单:还是那个房子,对于开门这个操作,我更换了一个远程解锁的门,那么我就可以通过这个远程连接的服务器远程解锁,这样我 ...

  9. putty和psftp命令行参数

    putty和psftp命令行参数 https://the.earth.li/~sgtatham/putty/latest/w32/putty.zip https://the.earth.li/~sgt ...

  10. javaweb常识

    Tomcat下载地址www.apache.org 在电脑中查看java版本:cmd中输入java -version tomcat解压后目录 bin:放可执行文件(如startup.bat   shut ...