一、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/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beanshttp://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 {@Testpublic 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 {@Testpublic 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 注解中。