Spring的第十二阶段(01):Spring实现AOP的简单使用

1、使用Spring实现AOP简单切面编程

需要导入工程的jar包
Spring的核心包

spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar

Spring的测试包

spring-test-4.0.0.RELEASE.jar

Spring日记相关包

commons-logging-1.1.3.jar
log4j-1.2.17.jar

Spring的AOP切面相关的包

spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

需要有的类

public interface Calculate {

	public int add(int num1, int num2);

	public int mul(int num1, int num2);

	public int div(int num1, int num2);

	public int sub(int num1, int num2);
}

@Component
public class Calculator implements Calculate {
	@Override
	public int add(int num1, int num2) {
		return num1 + num2;
	}

	@Override
	public int mul(int num1, int num2) {
		return num1 * num2;
	}

	@Override
	public int div(int num1, int num2) {
		return num1 / num2;
	}

	@Override
	public int sub(int num1, int num2) {
		return num1 - num2;
	}
}
@Aspect
@Component
public class LogUtil {
	@Before(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")
	public static void logBefore() {
		System.out.println("前置 日记 :【xxx】 方法调用前 。参数1是:xxxx");
	}

	@After(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")
	public static void logAfter() {
		System.out.println("后置 日记 :【xxxx】 方法调用前 。参数1是:xxxx");
	}

	@AfterReturning(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")
	public static void logAfterReturn() {
		System.out.println("返回之后: 日记 :【xxxxx】 方法调用前 。参数1是:xxxxxx");
	}

	@AfterThrowing(value = "execution(public int com.atguigu.aop.Calculator.add(int, int))")
	public static void logThrowException() {
		System.out.println("抛异常:日记 :【xxxxx】 方法调用前 。参数1是:xxxxxx");
	}

}

applicationContext.xml配置文件中的内容

<context:component-scan base-package="com.atguigu" />
<aop:aspectj-autoproxy />

测试代码

@ContextConfiguration(locations = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringAopTest {
	@Autowired
	private Calculate calculate;
	@Test
	public void test1() {
		System.out.println( "添加:" + calculate.add(1, 2));
	}
}

测试运行的结果

Spring的第十二阶段(01):Spring实现AOP的简单使用_第1张图片

2、Spring的切入点表达式

@PointCut切入点表达式语法格式是: execution(访问权限 返回值类型 方法全限定名(参数类型列表))

限定符:
*1)	匹配某全类名下,任意或多个方法。
表示匹配com.atguigu.aop.Calculator下以a打头的任意方法。并且返回值和两个参数都是int类型。
execution(public int com.atguigu.aop.Calculator.a*(int, int))

表示匹配com.atguigu.aop.Calculator下的任意方法。并且返回值和两个参数都是int类型。
execution(public int com.atguigu.aop.Calculator.*(int, int))

2)	在Spring中只有public权限能拦截到,访问权限可以省略(访问权限不能写*)。
// 权限省略,表示任意类型的访问权限 ,但Spring现在只支持public权限 
execution(int com.atguigu.aop.Calculator.*(int, int))

3)	匹配任意类型的返回值,可以使用 * 表示
// 表示任意类型的返回值
execution(* com.atguigu.aop.Calculator.*(int, int))

4)	匹配任意子包。
// 表示匹配com的子包
execution(* com.*.aop.Calculator.*(int, int))

5)	任意类型参数
// 表示第二个参数是任意类型
execution(* com.atguigu.aop.Calculator.*(int,*))

..:可以匹配多层路径,或任意多个任意类型参数
// 表示com和aop之间可以有任意层级的包
execution(* com..aop.Calculator.*(int,int))
// 表示第一个参数是int。之后可以有任意个任意类型的参数
execution(* com.atguigu.aop.Calculator.*(int,..))
模糊匹配:
// 表示任意返回值,任意方法全限定符,任意参数
execution(* *(..))
// 表示任意返回值,任意包名+任意方法名,任意参数
execution(* *.*(..))

精确匹配:
// int 返回值,com.atguigu.aop.Calculator类的add方法,两个int参数
execution(public int com.atguigu.aop.Calculator.add(int, int))

切入点表达式连接:&&|| 
// 表示需要同时满足两个表达式
	@Before("execution(public int com.atguigu.aop.Calculator.add(int, int))"
			+ " && "
+ "execution(public * com.atguigu.aop.Calculator.add(..))")

// 表示两个条件只需要满足一个,就会被匹配到
	@Before("execution(public int com.atguigu.aop.Calculator.add(int, int))"
			+ " || "
			+ "execution(public * com.atguigu.aop.Calculator.a*(int))")

3、Spring切面中的代理对象

在Spring中,可以对有接口的对象和无接口的对象分别进行代理。在使用上有些细微的差别。

  1. 如果被代理的对象实现了接口。在获取对象的时候,必须要以接口来接收返回的对象。

测试的代码:
在这里插入图片描述
Spring的第十二阶段(01):Spring实现AOP的简单使用_第2张图片

测试的结果:
在这里插入图片描述

  1. 被切面拦截的代理对象,如果没有实现接口。获取对象的时候使用对象类型本身
    Spring的第十二阶段(01):Spring实现AOP的简单使用_第3张图片

测试的代码:
Spring的第十二阶段(01):Spring实现AOP的简单使用_第4张图片

测试结果

在这里插入图片描述

你可能感兴趣的:(Java,spring,java,后端)