一、pom 中需要增加的依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>6.0.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>6.0.2</version>
</dependency>
二、前置通知
(一)基于 xml 的前置通知
首先,需要在 xml 文件里做如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="com.spring.aop"></context:component-scan>
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
然后,编写目标类:
package com.spring.aop;
import org.springframework.stereotype.Component;
@Component
public class Calculator{
public int add(int a, int b) {
System.out.println(a+b);
return a+b;
}
protected String sub(String a){
System.out.println(a);
return a;
}
}
之后,设置切面类:
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAspect {
@Before(value = "execution(public int com.spring.aop.Calculator.add(..))")
public void beforeMethod(){
System.out.println("Before Method");
}
}
最后,测试:
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
@Test
public void testAdd(){
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Calculator calculator = context.getBean(Calculator.class);
calculator.add(2,3);
calculator.sub("hello");
}
}
(二)基于全注解的前置通知
目标类:
package com.spring.aop;
import org.springframework.stereotype.Component;
@Component
public class Calculator{
public int add(int a, int b) {
System.out.println(a+b);
return a+b;
}
protected String sub(String a){
System.out.println(a);
return a;
}
}
配置类:
package com.spring.aop;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.spring.aop")
public class SpringConfig {
}
切面类:
package com.spring.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {
@Before(value = "execution(public int com.spring.aop.Calculator.add(..))")
public void beforeMethod(){
System.out.println("Before Method");
}
}
测试类:
package com.spring.aop;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestAop {
@Test
public void testAdd(){
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Calculator calculator = context.getBean(Calculator.class);
calculator.add(2,3);
calculator.sub("hello");
}
}
比较结果:
基于全注解的前置通知,等同于将
<context:component-scan base-package="com.spring.aop"></context:component-scan>
配置在配置类的 @ComponentScan 注解中;将
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
配置在切面类的 @EnableAspectJAutoProxy 注解中。