6、AOP实现切入
- AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
- 通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术
- AOP是OOP的延续,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
6.1实现切入的三种方式
6.1.1方式一,spring接口实现
- 定义一个实现切入的接口
| public interface BookService { |
| |
| void addBook(); |
| |
| void deleteBook(); |
| |
| void updateBook(); |
| |
| void queryBook(); |
| |
| } |
- 实现该接口的类
| public class BookServiceImpl implements BookService{ |
| @Override |
| public void addBook() { |
| System.out.println("增加了一本图书"); |
| } |
| |
| @Override |
| public void deleteBook() { |
| System.out.println("删除了一本图书"); |
| } |
| |
| @Override |
| public void updateBook() { |
| System.out.println("更新了一本图书"); |
| } |
| |
| @Override |
| public void queryBook() { |
| System.out.println("查询了一本图书"); |
| } |
| } |
- 定义切入前操作,实现MethodBeforeAdvice这个接口
| |
| public class BeforeLog implements MethodBeforeAdvice { |
| @Override |
| public void before(Method method, Object[] args, Object target) throws Throwable { |
| if(target != null){ |
| System.out.println(target.getClass().getName() + "执行力"+ method.getName() + "方法!"); |
| } |
| |
| } |
| } |
| |
| public class BeforeAfterLog implements MethodBeforeAdvice { |
| @Override |
| public void before(Method method, Object[] args, Object target) throws Throwable { |
| System.out.println("最开始的"); |
| } |
| } |
- 定义切入之后操作,实现AfterReturningAdvice接口
| public class AfterLog implements AfterReturningAdvice { |
| @Override |
| public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { |
| if(target != null){ |
| System.out.println(target.getClass().getName() + "执行力"+ method.getName() + "方法!"); |
| } |
| System.out.println("returnValue: "+ returnValue); |
| } |
| } |
注:可以实现多个切入操作
- spring的xml进行配置
| <?xml version="1.0" encoding="UTF-8"?> |
| <beans xmlns="http://www.springframework.org/schema/beans" |
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| xmlns:aop="http://www.springframework.org/schema/aop" |
| xsi:schemaLocation=" |
| http://www.springframework.org/schema/beans |
| https://www.springframework.org/schema/beans/spring-beans.xsd |
| http://www.springframework.org/schema/aop |
| https://www.springframework.org/schema/aop/spring-aop.xsd"> |
| |
| <bean id="bookServiceImpl" class="com.mhy.aop.service.BookServiceImpl"/> |
| <bean id="beforeLog" class="com.mhy.aop.Log.BeforeLog"/> |
| <bean id="afterLog" class="com.mhy.aop.Log.AfterLog"/> |
| <bean id="beforeAfterLog" class="com.mhy.aop.Log.BeforeAfterLog"/> |
| |
| <aop:config> |
| |
| <aop:pointcut id="pointcut" expression="execution(* com.mhy.aop.service.BookServiceImpl.*(..))"/> |
| |
| <aop:advisor advice-ref="beforeAfterLog" pointcut-ref="pointcut"/> |
| <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut"/> |
| <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/> |
| </aop:config> |
| |
| |
| </beans> |
- 测试
| @Test |
| public void test1(){ |
| ApplicationContext context = new ClassPathXmlApplicationContext("bookbeans.xml"); |
| |
| BookService bookService = context.getBean("bookServiceImpl", BookService.class); |
| |
| bookService.deleteBook(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
6.1.2方式二,自定义切入面实现
- 自定义一个切入点的类 DiyPointcut
| public class DiyPointcut { |
| public void before(){ |
| System.out.println("方法执行前"); |
| } |
| |
| public void after(){ |
| System.out.println("方法执行后"); |
| } |
| } |
- 在配置文件中配置
| <aop:config> |
| <aop:aspect ref="diyPointcut"> |
| |
| <aop:pointcut id="pointcut" expression="execution(* com.mhy.aop.service.BookServiceImpl.*(..))"/> |
| |
| <aop:before method="before" pointcut-ref="pointcut"/> |
| <aop:after method="after" pointcut-ref="pointcut"/> |
| </aop:aspect> |
| </aop:config> |
- 测试结果
6.1.3方式三,注解实现
- 开启注解驱动
| |
| <context:component-scan base-package="com.mhy.aop"/> |
| <context:annotation-config/> |
| |
| |
| <aop:aspectj-autoproxy /> |
| |
| |
| |
| |
| |
| |
- 切面类 AnnotationPointcut
- @Aspect:定义切面注解
- @After("execution( com.mhy.aop.service.BookServiceImpl.*(..))")*:定义切入点前的注解
- @After("execution( com.mhy.aop.service.BookServiceImpl.*(..))")*:定义切入点后的注解
- @Around("execution( com.mhy.aop.service.BookServiceImpl.*(..))")*:定义环绕切入点注解
| @Component(value = "annotationPointcut") |
| |
| @Aspect |
| public class AnnotationPointcut { |
| |
| |
| @Before("execution(* com.mhy.aop.service.BookServiceImpl.*(..))") |
| public void before(){ |
| System.out.println("========方法执行前========="); |
| } |
| |
| |
| @After("execution(* com.mhy.aop.service.BookServiceImpl.*(..))") |
| public void after(){ |
| System.out.println("========方法执行后========="); |
| } |
| |
| |
| @Around("execution(* com.mhy.aop.service.BookServiceImpl.*(..))") |
| public void around(ProceedingJoinPoint point) throws Throwable { |
| |
| System.out.println("环绕前"); |
| |
| point.proceed(); |
| System.out.println("环绕后"); |
| |
| System.out.println(point.getSignature()); |
| System.out.println(point); |
| |
| } |
| |
| } |
- 测试结果
| 环绕前 |
| ========方法执行前========= |
| 删除了一本图书 |
| ========方法执行后========= |
| 环绕后 |
| void com.mhy.aop.service.BookService.deleteBook() |
| execution(void com.mhy.aop.service.BookService.deleteBook()) |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)