(三)Spring 之AOP 详解
第一节:AOP 简介
AOP 简介:百度百科;
面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
--------
这里我先开头讲一个例子代码程序:
T.java:
1 package com.wishwzp.test; 2 3 import org.junit.Before; 4 import org.junit.Test; 5 import org.springframework.context.ApplicationContext; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 import com.wishwzp.service.StudentService; 9 10 11 public class T { 12 13 private ApplicationContext ac; 14 15 @Before 16 public void setUp() throws Exception { 17 ac=new ClassPathXmlApplicationContext("beans.xml"); 18 } 19 20 @Test 21 public void test1() { 22 StudentService studentService=(StudentService)ac.getBean("studentService"); 23 studentService.addStudent("张三"); 24 } 25 26 27 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 7 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 8 9 </beans>
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public void addStudent(String name) { 9 System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 System.out.println("完成学生"+name+"的添加"); 12 } 13 14 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public void addStudent(String name); 6 }
运行结果显示:
开始添加学生张三
添加学生张三
完成学生张三的添加
--------------
第二节:Spring AOP 实例
1,前置通知;
2,后置通知;
3,环绕通知;
4,返回通知;
5,异常通知;
1,前置通知;
T.java:
1 package com.wishwzp.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.wishwzp.service.StudentService; 7 8 9 public class T { 10 11 public static void main(String[] args) { 12 ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); 13 StudentService studentService=(StudentService)ac.getBean("studentService"); 14 studentService.addStudent("张三"); 15 16 } 17 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 10 <!-- 注入bean,StudentServiceAspect --> 11 <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean> 12 13 <!-- 注入bean,StudentServiceImpl --> 14 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 15 16 <!-- 配置AOP --> 17 <aop:config> 18 <aop:aspect id="studentServiceAspect" ref="studentServiceAspect"> 19 <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/> 20 <aop:before method="doBefore" pointcut-ref="businessService"/> 21 </aop:aspect> 22 </aop:config> 23 </beans>
StudentServiceAspect.java:
1 package com.wishwzp.advice; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class StudentServiceAspect { 7 8 public void doBefore(JoinPoint jp){ 9 System.out.println("类名:"+jp.getTarget().getClass().getName()); 10 System.out.println("方法名:"+jp.getSignature().getName()); 11 System.out.println("开始添加学生:"+jp.getArgs()[0]); 12 } 13 14 }
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public void addStudent(String name) { 9 // System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 // System.out.println("完成学生"+name+"的添加"); 12 } 13 14 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public void addStudent(String name); 6 }
运行结果显示:
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生张三
2,后置通知;
T.java:
1 package com.wishwzp.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.wishwzp.service.StudentService; 7 8 9 public class T { 10 11 public static void main(String[] args) { 12 ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); 13 StudentService studentService=(StudentService)ac.getBean("studentService"); 14 studentService.addStudent("张三"); 15 16 } 17 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 10 <!-- 注入bean,StudentServiceAspect --> 11 <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean> 12 13 <!-- 注入bean,StudentServiceImpl --> 14 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 15 16 <!-- 配置AOP --> 17 <aop:config> 18 <aop:aspect id="studentServiceAspect" ref="studentServiceAspect"> 19 <!-- 配置执行切点路径和id --> 20 <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/> 21 <!-- 前置通知 --> 22 <aop:before method="doBefore" pointcut-ref="businessService"/> 23 <!-- 后置通知 --> 24 <aop:after method="doAfter" pointcut-ref="businessService"/> 25 </aop:aspect> 26 </aop:config> 27 </beans>
StudentServiceAspect.java:
1 package com.wishwzp.advice; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class StudentServiceAspect { 7 8 //前置通知 9 public void doBefore(JoinPoint jp){ 10 System.out.println("类名:"+jp.getTarget().getClass().getName()); 11 System.out.println("方法名:"+jp.getSignature().getName()); 12 System.out.println("开始添加学生:"+jp.getArgs()[0]); 13 } 14 15 //后置通知 16 public void doAfter(JoinPoint jp){ 17 System.out.println("类名:"+jp.getTarget().getClass().getName()); 18 System.out.println("方法名:"+jp.getSignature().getName()); 19 System.out.println("学生添加完成:"+jp.getArgs()[0]); 20 } 21 }
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public void addStudent(String name) { 9 // System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 // System.out.println("完成学生"+name+"的添加"); 12 } 13 14 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public void addStudent(String name); 6 }
运行结果显示:
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生张三
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三
3,环绕通知;
T.java:
1 package com.wishwzp.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.wishwzp.service.StudentService; 7 8 9 public class T { 10 11 public static void main(String[] args) { 12 ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); 13 StudentService studentService=(StudentService)ac.getBean("studentService"); 14 studentService.addStudent("张三"); 15 16 } 17 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 10 <!-- 注入bean,StudentServiceAspect --> 11 <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean> 12 13 <!-- 注入bean,StudentServiceImpl --> 14 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 15 16 <!-- 配置AOP --> 17 <aop:config> 18 <aop:aspect id="studentServiceAspect" ref="studentServiceAspect"> 19 <!-- 配置执行切点路径和id --> 20 <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/> 21 <!-- 前置通知 --> 22 <aop:before method="doBefore" pointcut-ref="businessService"/> 23 <!-- 后置通知 --> 24 <aop:after method="doAfter" pointcut-ref="businessService"/> 25 <!-- 环绕通知 --> 26 <aop:around method="doAround" pointcut-ref="businessService"/> 27 </aop:aspect> 28 </aop:config> 29 </beans>
StudentServiceAspect.java:
1 package com.wishwzp.advice; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class StudentServiceAspect { 7 8 //前置通知 9 public void doBefore(JoinPoint jp){ 10 System.out.println("类名:"+jp.getTarget().getClass().getName()); 11 System.out.println("方法名:"+jp.getSignature().getName()); 12 System.out.println("开始添加学生:"+jp.getArgs()[0]); 13 } 14 15 //后置通知 16 public void doAfter(JoinPoint jp){ 17 System.out.println("类名:"+jp.getTarget().getClass().getName()); 18 System.out.println("方法名:"+jp.getSignature().getName()); 19 System.out.println("学生添加完成:"+jp.getArgs()[0]); 20 } 21 22 //环绕通知,这里添加了返回值 23 public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ 24 System.out.println("添加学生前"); 25 Object retVal=pjp.proceed(); 26 System.out.println(retVal); 27 System.out.println("添加学生后"); 28 return retVal; 29 } 30 }
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public String addStudent(String name) { 9 // System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 // System.out.println("完成学生"+name+"的添加"); 12 return name; 13 } 14 15 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public String addStudent(String name); 6 }
运行结果显示:
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生前
添加学生张三
张三
添加学生后
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三
4,返回通知;
T.java:
1 package com.wishwzp.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.wishwzp.service.StudentService; 7 8 9 public class T { 10 11 public static void main(String[] args) { 12 ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); 13 StudentService studentService=(StudentService)ac.getBean("studentService"); 14 studentService.addStudent("张三"); 15 16 } 17 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 10 <!-- 注入bean,StudentServiceAspect --> 11 <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean> 12 13 <!-- 注入bean,StudentServiceImpl --> 14 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 15 16 <!-- 配置AOP --> 17 <aop:config> 18 <aop:aspect id="studentServiceAspect" ref="studentServiceAspect"> 19 <!-- 配置执行切点路径和id --> 20 <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/> 21 <!-- 前置通知 --> 22 <aop:before method="doBefore" pointcut-ref="businessService"/> 23 <!-- 后置通知 --> 24 <aop:after method="doAfter" pointcut-ref="businessService"/> 25 <!-- 环绕通知 --> 26 <aop:around method="doAround" pointcut-ref="businessService"/> 27 <!-- 返回通知 --> 28 <aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/> 29 </aop:aspect> 30 </aop:config> 31 </beans>
StudentServiceAspect.java:
1 package com.wishwzp.advice; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class StudentServiceAspect { 7 8 //前置通知 9 public void doBefore(JoinPoint jp){ 10 System.out.println("类名:"+jp.getTarget().getClass().getName()); 11 System.out.println("方法名:"+jp.getSignature().getName()); 12 System.out.println("开始添加学生:"+jp.getArgs()[0]); 13 } 14 15 //后置通知 16 public void doAfter(JoinPoint jp){ 17 System.out.println("类名:"+jp.getTarget().getClass().getName()); 18 System.out.println("方法名:"+jp.getSignature().getName()); 19 System.out.println("学生添加完成:"+jp.getArgs()[0]); 20 } 21 22 //环绕通知,这里添加了返回值 23 public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ 24 System.out.println("添加学生前"); 25 Object retVal=pjp.proceed(); 26 System.out.println(retVal); 27 System.out.println("添加学生后"); 28 return retVal; 29 } 30 31 //返回通知 32 public void doAfterReturning(JoinPoint jp){ 33 System.out.println("返回通知"); 34 } 35 }
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public String addStudent(String name) { 9 // System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 // System.out.println("完成学生"+name+"的添加"); 12 return name; 13 } 14 15 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public String addStudent(String name); 6 }
运行结果显示:
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生前
添加学生张三
返回通知
张三
添加学生后
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三
5,异常通知;
T.java:
1 package com.wishwzp.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 import com.wishwzp.service.StudentService; 7 8 9 public class T { 10 11 public static void main(String[] args) { 12 ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); 13 StudentService studentService=(StudentService)ac.getBean("studentService"); 14 studentService.addStudent("张三"); 15 16 } 17 }
beans.xml:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop.xsd"> 9 10 <!-- 注入bean,StudentServiceAspect --> 11 <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean> 12 13 <!-- 注入bean,StudentServiceImpl --> 14 <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean> 15 16 <!-- 配置AOP --> 17 <aop:config> 18 <aop:aspect id="studentServiceAspect" ref="studentServiceAspect"> 19 <!-- 配置执行切点路径和id --> 20 <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/> 21 <!-- 前置通知 --> 22 <aop:before method="doBefore" pointcut-ref="businessService"/> 23 <!-- 后置通知 --> 24 <aop:after method="doAfter" pointcut-ref="businessService"/> 25 <!-- 环绕通知 --> 26 <aop:around method="doAround" pointcut-ref="businessService"/> 27 <!-- 返回通知 --> 28 <aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/> 29 <!-- 异常通知 --> 30 <aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/> 31 </aop:aspect> 32 </aop:config> 33 </beans>
StudentServiceAspect.java:
1 package com.wishwzp.advice; 2 3 import org.aspectj.lang.JoinPoint; 4 import org.aspectj.lang.ProceedingJoinPoint; 5 6 public class StudentServiceAspect { 7 8 //前置通知 9 public void doBefore(JoinPoint jp){ 10 System.out.println("类名:"+jp.getTarget().getClass().getName()); 11 System.out.println("方法名:"+jp.getSignature().getName()); 12 System.out.println("开始添加学生:"+jp.getArgs()[0]); 13 } 14 15 //后置通知 16 public void doAfter(JoinPoint jp){ 17 System.out.println("类名:"+jp.getTarget().getClass().getName()); 18 System.out.println("方法名:"+jp.getSignature().getName()); 19 System.out.println("学生添加完成:"+jp.getArgs()[0]); 20 } 21 22 //环绕通知,这里添加了返回值 23 public Object doAround(ProceedingJoinPoint pjp) throws Throwable{ 24 System.out.println("添加学生前"); 25 Object retVal=pjp.proceed(); 26 System.out.println(retVal); 27 System.out.println("添加学生后"); 28 return retVal; 29 } 30 31 //返回通知 32 public void doAfterReturning(JoinPoint jp){ 33 System.out.println("返回通知"); 34 } 35 36 //异常通知 37 public void doAfterThrowing(JoinPoint jp,Throwable ex){ 38 System.out.println("异常通知"); 39 System.out.println("异常信息:"+ex.getMessage()); 40 } 41 }
StudentServiceImpl.java:
1 package com.wishwzp.service.impl; 2 3 import com.wishwzp.service.StudentService; 4 5 public class StudentServiceImpl implements StudentService{ 6 7 @Override 8 public String addStudent(String name) { 9 // System.out.println("开始添加学生"+name); 10 System.out.println("添加学生"+name); 11 System.out.println(1/0); 12 // System.out.println("完成学生"+name+"的添加"); 13 return name; 14 } 15 16 }
StudentService.java:
1 package com.wishwzp.service; 2 3 public interface StudentService { 4 5 public String addStudent(String name); 6 }
运行结果显示:
【推荐】FFA 2024大会视频回放:Apache Flink 的过去、现在及未来
【推荐】中国电信天翼云云端翼购节,2核2G云服务器一口价38元/年
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 聊一聊坑人的 C# MySql.Data SDK
· 使用 .NET Core 实现一个自定义日志记录器
· [杂谈]如何选择:Session 还是 JWT?
· 硬盘空间消失之谜:Linux 服务器存储排查与优化全过程
· JavaScript是按顺序执行的吗?聊聊JavaScript中的变量提升
· 2000 Star,是时候为我的开源项目更新下功能了
· 好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!
· 工作中这样用MQ,很香!
· 使用 .NET Core 实现一个自定义日志记录器
· 没事别想不开去创业!