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 />


相关文章
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
9天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
35 9
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
14天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
29天前
|
前端开发 Java 数据库
SpringBoot学习
【10月更文挑战第7天】Spring学习
34 9
|
30天前
|
XML Java 数据格式
Spring学习
【10月更文挑战第6天】Spring学习
19 1
|
10天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
1月前
|
Java 测试技术 开发者
springboot学习四:Spring Boot profile多环境配置、devtools热部署
这篇文章主要介绍了如何在Spring Boot中进行多环境配置以及如何整合DevTools实现热部署,以提高开发效率。
56 2
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
162 2