Day28——前置通知、后置通知

一. 知识储备

1.1 前置通知

  • 在方法前添加@Before注解,但是会报错,它说没有添加相关的属性值。其实是指定value=“xxx”。

  • value=“xxx”: 表示切入点的表达式,即你要在哪个方法前使用这个前置通知。前面讲到切入点类似于查找数据库记录里面的条件

  • 所以要表示某个方法,必须要说明它的修饰符 返回值类型 所在类的全类名.方法名(参数列表的类型)如下图:
    Day28——前置通知、后置通知

  • 写好表达式后,我们就可以在方法里面写日志功能。这时要用到连接点JoinPoint。

  • 连接点:即相当于数据库里面的记录,包含当前相关的信息。而在刚刚的切入点表达式

value="public int com.atguigu.spring.aop.aspectJ.ArithmeticCalculatorImpl.add(int, int)"
  • 所以此时的连接点就是这个add方法。它包含这个add方法的所有信息(如方法名,形参),如下:
//方法名
String methodName = joinPoint.getSignature().getName();
//方法的参数列表
Object[] args = joinPoint.getArgs();

解释: 上面代码中的getSignature()是获取方法的签名,方法的签名包含方法名和参数列表

1.2 前置通知例子

ArithmeticCalculator.java

package com.atguigu.spring.aop.aspectJ;

/**
 * 算数计算器
 * @author user
 *
 */
public interface ArithmeticCalculator {
    /**
     * 加法
     * @param i
     * @param j
     * @return
     */
	public int add(int i, int j);
	
	/**
	 * 减法
	 * @param i
	 * @param j
	 * @return
	 */
	public int sub(int i, int j);
	
	/**
	 * 乘法
	 * @param i
	 * @param j
	 * @return
	 */
	public int mul(int i, int j);
	
	/**
	 * 除法
	 * @param i
	 * @param j
	 * @return
	 */
	public int div(int i, int j);
	
}

ArithmeticCalculatorImpl.java

package com.atguigu.spring.aop.aspectJ;

import org.springframework.stereotype.Component;

@Component
public class ArithmeticCalculatorImpl implements ArithmeticCalculator {

	@Override
	public int add(int i, int j) {
		// TODO Auto-generated method stub
		int result = i + j;
		return result;
	}

	@Override
	public int sub(int i, int j) {
		// TODO Auto-generated method stub
		int result = i - j;
		return result;
	}

	@Override
	public int mul(int i, int j) {
		// TODO Auto-generated method stub
		int result = i * j;
		return result;
	}

	@Override
	public int div(int i, int j) {
		// TODO Auto-generated method stub
		int result = i / j;
		return result;
	}

}

spring-annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
   
   <!-- 组件扫描 -->
   <context:component-scan base-package="com.atguigu.spring.aop.aspectJ" >
    </context:component-scan>

    <!-- 开启AOP注解支持,为切面所能作用到的目标类生成代理 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    
</beans>

LoggingAspect.java

package com.atguigu.spring.aop.aspectJ;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 切面:日志切面
 * @author user
 *
 */
@Component //标识为一个组件
@Aspect //标识为一个切面
public class LoggingAspect {

	/**
	 * 前置通知:在方法执行之前执行
	 * value: 切入点表达式
	 * 连接点对象: JoinPoint , 包含当前连接点相关信息(即当前作用的方法,即切入点表达式里面的方法)
	 * 
	 */
	@Before(value = "execution(public int com.atguigu.spring.aop.aspectJ.ArithmeticCalculatorImpl.add(int, int))")
	public void beforeMethod(JoinPoint joinPoint) {
		
		//方法名
		String methodName = joinPoint.getSignature().getName();
		
		//方法的参数列表
		Object[] args = joinPoint.getArgs();
		
		System.out.println("LoggingAspect==> The method " + methodName + " begin with : " + Arrays.asList(args));
		
	}
	
}

Main.java

package com.atguigu.spring.aop.aspectJ;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
         public static void main(String[] args) {
			ApplicationContext context = 
					new ClassPathXmlApplicationContext("spring-annotation.xml");
			ArithmeticCalculator ac = 
					context.getBean("arithmeticCalculatorImpl", ArithmeticCalculator.class);
			int result = ac.add(1, 1);
			System.out.println("Main==>: " + result);
			
		}
}

1.3 后置通知例子

在LoggingAspect.java中添加以下方法

/**
	 * 后置通知:在方法执行之后,不管目标方法有无抛出异常都会执行
	 * 切入点表达式:
	 *     * : 任意修饰符任意返回值
	 *     * : 包下的任意类
	 *     * :类中任意方法
	 *     ..: 任意参数列表
	 */
	@After(value="execution(* com.atguigu.spring.aop.aspectJ.*.*(..))")
	public void afterMethod(JoinPoint joinPoint) {
		String methodName = joinPoint.getSignature().getName();
		System.out.println("LoggingAspect==> The method " + methodName + " ends.");
	}
Day28——前置通知、后置通知Day28——前置通知、后置通知 Android_la 发布了194 篇原创文章 · 获赞 16 · 访问量 1万+ 私信 关注
上一篇:050_代码生成器


下一篇:LAMP之一:apache、mysql、php的安装及互联互通