Spring的核心AOP及代理模式(“最易懂得Spring学习”)(一)

简介: AOP1. 什么是AOP2. Aop在Spring中的作用3. 使用Spring实现AOP方式一:使用Spring的api接口[主要是api接口]方式二:自定义来实现aop[主要是切面]方式三:使用注解来实现aop

🐳点击送你到《简单了解了Spring以及IOC的理论推导》

🐳点击送你到《Spring中的IOC和DI》


AOP


1. 什么是AOP


AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低提高程序的可重用性,同时提高了开发的效率。


AOP


  • 日志记录
  • 性能统计
  • 安全控制
  • 事务处理
  • 异常处理等


Spring AOP切面简单理解就是一把刀,在执行过程中可以随意地插入或拔出。


微信图片_20211230150123.png


2. Aop在Spring中的作用


提供声明式事务;允许用户自定义切面


  • 横切关注点:对哪写方法进行拦截,拦截后又怎么处理,与我们业务逻辑无关的,但我们需要关注的部分,就是横切关注点,如日志,安全,缓存,事务等。跨越应用程序多个模块的方法或功能。
  • 切面(ASPECT):横切关注点被模块化的特殊对象,即它是一个类
  • 通知(Advice):切面必须要完成的工作,即它是类中的一个方法
  • 目标(Target):被通知对象,也就是代理的目标对象。
  • 代理(Proxy):向目标对象应用通知后创建的对象。
  • 切入点(PointCut):切面通知执行的”地点“的定义
  • 连接点(JointPoint):与切入点匹配的执行点。
  • 织入(weave):将切面应用到目标对象并导致代理对象创建的过程。


微信图片_20211230150246.png

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice


微信图片_20211230150229.png


3. 使用Spring实现AOP


【重点】使用AOP织入,需要导入一个依赖包


<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
    </dependency>
</dependencies>


方式一:使用Spring的api接口[主要是api接口]


UserService

package com.hxl.service;
public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void select();
}

UserServiceImpl

package com.hxl.service;
public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加了一个用户");
    }
    public void delete() {
        System.out.println("删除了一个用户");
    }
    public void update() {
        System.out.println("修改了一个用户");
    }
    public void select() {
        System.out.println("查询了一个用户");
    }
}

applicationContext.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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--注册bean-->
    <bean id="userService" class="com.hxl.service.UserServiceImpl"/>
    <bean id="log" class="com.hxl.log.Log"/>
    <bean id="afterLog" class="com.hxl.log.LogAfter"/>
    <!--使用原生的Spring API接口-->
    <!--配置aop:需要导入aop的约束-->
    <aop:config>
        <!--切入点;expression:表达式,execution(要执行的位置,修饰词,返回值,类名,方法名,参数)-->
        <aop:pointcut id="pointCut" expression="execution(* com.hxl.service.UserServiceImpl.*(..))"/>
        <!--执行环绕增加-->
        <aop:advisor advice-ref="log" pointcut-ref="pointCut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointCut"/>
    </aop:config>
</beans>

测试:

import com.hxl.service.UserService;
import com.hxl.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //注意点:动态代理代理的是接口
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
}


方式二:自定义来实现aop[主要是切面]


DiyPointCut

package com.hxl.diy;
public class DiyPointCut {
    public void before(){
        System.out.println("====方法执行前====");
    }
    public void after(){
        System.out.println("====方法执行后====");
    }
}
<!--方式二:自定义类-->
<bean id="diy" class="com.hxl.diy.DiyPointCut"/>
<aop:config>
    <!--自定义切面,ref要引用的类-->
    <aop:aspect ref="diy">
        <!--切入点-->
        <aop:pointcut id="point" expression="execution(* com.hxl.service.UserServiceImpl.*(..))"/>
        <!--通知-->
        <aop:before method="before" pointcut-ref="point"/>
        <aop:after method="after" pointcut-ref="point"/>
    </aop:aspect>
</aop:config>


方式三:使用注解来实现aop


package com.hxl.diy;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//方式三:使用注解方式实现aop
@Aspect//标注这个类是一个切面
public class AnnotationPointCut {
    @Before("execution(* com.hxl.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("====方法执行前====");
    }
    @After("execution(* com.hxl.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("====方法执行后====");
    }
    //在环绕增强中,我们可以给定一个参数,代表我们要获取处理切入的点
    @Around("execution(* com.hxl.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("====环绕前====");
        Signature signature = jp.getSignature();//获得签名
        System.out.println("signature:" + signature);
        //执行方法
        Object proceed = jp.proceed();
        System.out.println("=====环绕后====");
    }
}
<!--方式三:-->
<bean id="annotationPointCut" class="com.hxl.diy.AnnotationPointCut"/>
<!--开启注解支持
    JDK(默认proxy-target-class="false")
    cglib(proxy-target-class="true")
    -->
<aop:aspectj-autoproxy />


相关文章
|
2月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。
|
3月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
461 0
|
2月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
7月前
|
监控 安全 Java
Spring AOP实现原理
本内容主要介绍了Spring AOP的核心概念、实现机制及代理生成流程。涵盖切面(Aspect)、连接点(Join Point)、通知(Advice)、切点(Pointcut)等关键概念,解析了JDK动态代理与CGLIB代理的原理及对比,并深入探讨了通知执行链路和责任链模式的应用。同时,详细分析了AspectJ注解驱动的AOP解析过程,包括切面识别、切点表达式匹配及通知适配为Advice的机制,帮助理解Spring AOP的工作原理与实现细节。
1160 13
|
4月前
|
人工智能 监控 安全
如何快速上手【Spring AOP】?核心应用实战(上篇)
哈喽大家好吖~欢迎来到Spring AOP系列教程的上篇 - 应用篇。在本篇,我们将专注于Spring AOP的实际应用,通过具体的代码示例和场景分析,帮助大家掌握AOP的使用方法和技巧。而在后续的下篇中,我们将深入探讨Spring AOP的实现原理和底层机制。 AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的核心特性之一,它能够帮助我们解决横切关注点(如日志记录、性能统计、安全控制、事务管理等)的问题,提高代码的模块化程度和复用性。
|
4月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
6月前
|
安全 Java 数据库
Spring Boot 框架深入学习示例教程详解
本教程深入讲解Spring Boot框架,先介绍其基础概念与优势,如自动配置、独立运行等。通过搭建项目、配置数据库等步骤展示技术方案,并结合RESTful API开发实例帮助学习。内容涵盖环境搭建、核心组件应用(Spring MVC、Spring Data JPA、Spring Security)及示例项目——在线书店系统,助你掌握Spring Boot开发全流程。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
1023 2
|
安全 Java Spring
Spring之Aop的底层原理
Spring之Aop的底层原理
|
设计模式 Java uml
Spring AOP 原理
Spring AOP 原理
127 0