1、首先导入jar包:
<properties>
<spring.v>4.2.8.RELEASE</spring.v>
<mybatis.version>3.2.8</mybatis.version>
<mybatis.spring.version>1.2.2</mybatis.spring.version>
<mysql.jdbc.driver.version>5.1.39</mysql.jdbc.driver.version>
<aspectj.v>1.7.4</aspectj.v>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.v}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.v}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.v}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.v}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.v}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.v}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.v}</version>
</dependency>
-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.v}</version>
<scope>test</scope>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.v}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.v}</version>
</dependency>
2、申明一个切面
package com.spring.aspect.service.aspect;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 面向切面编程
* @author 张秋平
*
*/
@Order(2)//如果有多个切面,这个注解标识执行的顺序
@Aspect
@Component
public class LoggingAspect {
/**
* 声明一个切入点表达式方法,重用切入点表达式,其他地方可以重用
*/
@Pointcut("execution(public * com.spring.aspect.service.IAspectDemo.*(..))")
public void declareJoinPointExpression(){
System.out.println("declareJoinPointExpression------>>>>>>>");
}
/**
* 前置通知:重用切入点表达式:declareJoinPointExpression()与上面方法名称对应
* 在com.spring.aspect.service.IAspectDemo接口的每一个实现类的每一个方法开始执行之前执行一段代码
*/
@Before("declareJoinPointExpression()")
public void beforeMethod(JoinPoint joinPoint){
System.out.println("The "+joinPoint.getSignature().getName()+"method begins ---> param:"+Arrays.toString(joinPoint.getArgs()));
}
/**
* 后置通知
* 在方法执行之后执行代码,抛出异常也会执行
* @param joinPoint
*/
@After("execution(public * com.spring.aspect.service.IAspectDemo.*(..))")
public void afterMethod(JoinPoint joinPoint){
System.err.println("The "+joinPoint.getSignature().getName()+"method end ---> param:"+Arrays.toString(joinPoint.getArgs()));
}
/**
* 返回值通知--->可以访问到方法的返回值 result就是方法的返回值
* 在方法正常执行结束后执行的代码
* @param joinPoint 连接对象
* @param result 方法返回值
*/
@AfterReturning(returning="result",value="execution(public * com.spring.aspect.service.IAspectDemo.*(..))")
public void afterReturing(JoinPoint joinPoint,Object result){
System.out.println("return----->"+result);
}
/**
* 异常通知
* afterThrowing(JoinPoint joinPoint,Exception ex)可以指定特殊异常,比如空指针异常,如果方法不是抛出空指针异常则不会执行
* @param joinPoint 链接对象
* @param ex 方法抛出的异常
*/
@AfterThrowing(value="execution(public * com.spring.aspect.service.IAspectDemo.*(..))",throwing="ex")
public void afterThrowing(JoinPoint joinPoint,Exception ex){
System.out.println("===================");
ex.printStackTrace();
}
/**
* 环绕通知
* 1、必须有ProceedingJoinPoint对象参数,ProceedingJoinPoint决定是否调用目标方法
* 2、类型于java的动态代理
* 3、必须有返回值,返回值就是目标方法的返回值
* @param pjd
*/
// @Around("execution(public * com.spring.aspect.service.IAspectDemo.*(..))")
// public Object aroundMethod(ProceedingJoinPoint pjd){
// Object result = null;
// try {
// System.err.println("前置通知");
// result = pjd.proceed();
// System.err.println("返回通知1--->"+result);
// } catch (Throwable e) {
// System.err.println("异常通知");
// throw new RuntimeException(e);
// }
// System.out.println("后置通知2");
// return null;
//
// }
}
3、spring-aop.xml配置
<!-- 配置自动扫面包 -->
<context:component-scan base-package="com.spring.aspect.*"></context:component-scan>
<!-- 配置自动匹配aspectJ 注解的Java类生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
4、执行测试,编写一个接口以及实现类:
package com.spring.aspect.service;
public interface IAspectDemo {
String hello(String name);
String skip(String what);
}
package com.spring.aspect.service.impl;
import org.springframework.stereotype.Component;
import com.spring.aspect.service.IAspectDemo;
@Component("aspectDemo")
public class AspectDemo implements IAspectDemo {
public String hello(String name) {
System.out.println("hello:"+name);
return "hello:"+name;
}
public String skip(String what) {
System.out.println("skip "+what);
return "skip "+what;
}
}
package com.spring.aspect.service;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopMain {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("application-aspect.xml");
IAspectDemo demo = (IAspectDemo) ac.getBean("aspectDemo");
demo.hello("张san");
demo.skip("绳");
}
}