AOP(Aspect Oriented Programming) 即面向切面编程 ,不同于
OOP(Object Oriented Programming) 面向对象编程,AOP关注的方向是横向的,而OOP关注的方向是纵向的,spring AOP是spring关键组件之一,它是AOP概念的具体实现方案,是对spring IOC 的补充,但是spring IOC不依赖spring AOP。
① 引入spring-aop 和 spring-aspects依赖
② 定义需要拦截的bean
package com.springtest.model;public class AopTestBean {public void printStr(String str) {if (str == null) {throw new RuntimeException("str 为空!");}System.out.println("com.springtest.model.AopTestBean 输出: " + str);}
}
③ 定义切面(其中包括切点,通知等)
package com.springtest.aop;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;@Aspect
public class AspectJTest {//切点@Pointcut("execution(* *.printStr(..))")public void printStr() {}//前置通知@Before("printStr()")public void beforePrintStr() {System.out.println("beforePrintStr");}//后置通知@After("printStr()")public void afterPrintStr() {System.out.println("afterPrintStr");}//环绕通知@Around("printStr()")public Object aroundPrintStr(ProceedingJoinPoint p) throws Throwable {System.out.println("aroundPrintStr start");Object o = p.proceed();System.out.println("aroundPrintStr end");return o;}//返回通知@AfterReturning("printStr()")public void afterReturningPrintStr() {System.out.println("afterReturningPrintStr");}//异常通知@AfterThrowing("printStr()")public void afterThrowingPrintStr() {System.out.println("afterThrowingPrintStr");}
}
④ 在配置文件中启用aop,以及在容器中初始化测试bean和切面
aop-test.xml
⑤ 编写测试类
import com.springtest.model.AopTestBean;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringXmlContextTest {@Testpublic void aopTest() {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("aop-test.xml");AopTestBean aopTestBean = (AopTestBean) classPathXmlApplicationContext.getBean("aopTestBean");aopTestBean.printStr("天气晴朗");System.out.println("----------------------------------------------");aopTestBean.printStr(null);}}
测试结果如下:
"C:\Program Files\Java\jdk1.8.0_121\bin\java.exe" -agentlib:jdwp=transport=dt_socket,address=127.0.0.1:6431,suspend=y,server=n -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:C:\Users\Administrator\.IntelliJIdea2019.1\system\captureAgent\debugger-agent.jar -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2019.1\plugins\junit\lib\junit5-rt.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\rt.jar;D:\workspace\spring-test-ws\beaninit\target\test-classes;D:\workspace\spring-test-ws\beaninit\target\classes;D:\m2\repository\org\springframework\spring-core\5.0.0.RELEASE\spring-core-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-jcl\5.0.0.RELEASE\spring-jcl-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-context\5.0.0.RELEASE\spring-context-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-beans\5.0.0.RELEASE\spring-beans-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-expression\5.0.0.RELEASE\spring-expression-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-aop\5.0.0.RELEASE\spring-aop-5.0.0.RELEASE.jar;D:\m2\repository\org\springframework\spring-aspects\5.0.0.RELEASE\spring-aspects-5.0.0.RELEASE.jar;D:\m2\repository\org\aspectj\aspectjweaver\1.8.11\aspectjweaver-1.8.11.jar;D:\m2\repository\junit\junit\4.12\junit-4.12.jar;D:\m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 SpringXmlContextTest,aopTest
Connected to the target VM, address: '127.0.0.1:6431', transport: 'socket'
五月 05, 2021 5:12:11 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6dde5c8c: startup date [Wed May 05 17:12:11 CST 2021]; root of context hierarchy
五月 05, 2021 5:12:11 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [aop-test.xml]
aroundPrintStr start
beforePrintStr
com.springtest.model.AopTestBean 输出: 天气晴朗
aroundPrintStr end
afterPrintStr
afterReturningPrintStr
----------------------------------------------
aroundPrintStr start
beforePrintStr
afterPrintStr
afterThrowingPrintStrjava.lang.RuntimeException: str 为空!at com.springtest.model.AopTestBean.printStr(AopTestBean.java:7)at com.springtest.model.AopTestBean$$FastClassBySpringCGLIB$$13686d5d.invoke(
官方文档:
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop