【Spring】AOP原来如此

2024-01-01 15:20
文章标签 java spring aop 原来如此

本文主要是介绍【Spring】AOP原来如此,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

AOP概述

什么是AOP的技术?

  • 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程
  • AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构
  • AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范
  • 通过预编译方式或者运行期动态代理实现程序功能的统一维护的一种技术
  • AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型
  • 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率

AOP:面向切面编程.(思想.---解决OOP遇到一些问题)

        AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

为什么要学习AOP,可以在不修改源代码的前提下,对程序进行增强!!


说到增强你觉得AOP和谁比较像? 没错是代理 ,不了解看这篇文章00=》【javaSE】代理并不难-CSDN博客


AOP的底层原 理

JDK的动态代理技术

​ 1、为接口创建代理类的字节码文件

​ 2、使用ClassLoader将字节码文件加载到JVM

​ 3、创建代理类实例对象,执行对象的目标方法

cglib代理技术

1、创建拦截器:继承MethodInterceptor的 intercepter的类,在拦截器中重写intercerpt( )方法,就是增强+目标对象的方法调用,返回拦截器

2、在测试这边创建一个类似proxy的子类对象enhancer,然后设置这个代理对象的类型(setSuperclass(目标对象的类型.class完成))

3、创建一个拦截器,enhancer通过去设置回调函数(setCallback(拦截器))

4、创建代理对象enhancer.create(),代理对象的类型要和目标对象一致哈,然后通过代理对象去完成方法的调用


 AOP相关的术语

  • Joinpoint(连接点) 所谓连接点是指那些被拦截到的点。在spring,这些点指的是方法,因为spring只支持方法类型的连接点
  • Pointcut(切入点) -- 所谓切入点是指我们要对哪些Joinpoint进行拦截的定义
  • Advice(通知/增强)-- 所谓通知是指拦截到Joinpoint之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,最终通知,环绕通知(切面要完成的功能)
  • Target(目标对象)-- 代理的目标对象
  • Weaving(织入)-- 是指把增强应用到目标对象来创建新的代理对象的过程
  • Proxy(代理)-- 一个类被AOP织入增强后,就产生一个结果代理类
  • Aspect(切面)-- 是切入点和通知的结合,以后咱们自己来编写和配置的

基于代理类的AOP

Spring的AOP代理默认用的就是JDK代理方式来实现的,在Spring中,ProxyFactoryBean是创建AOP代理的最基本方法(不常用,后面有更好的方法)

ProxyFactoryBean

ProxyFactoryBean是FactoryBean接口的实现类,FactoryBean负责实例化一个Bean,而ProxyFactoryBean负责为其他Bean创建代理实例。

ProxtFactoryBean类的常用配置属性

target

代理的目标对象

proxyInterfaces

代理要实现的接口,如果有多个接口,可以使用一些形式赋值

...

proxyTargetClass

是否对类代理而不是接口,设置为true时,使用CGLIB代理

interceptorNames

需要织入目标的Advice

singleton

返回的代理是否为单实例,默认为true

optimize

设置为true,强制使用CGLIB

下面是一个典型例子:

导包

在核心jar包基础上导入AOP的jar包,

  • Spring-aop-4.3.6.RELEASE.jar
  • aopalliance-1.0.jar
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.0.2.RELEASE</version>
</dependency>
<dependency><groupId>aopalliance</groupId><artifactId>aopalliance</artifactId><version>1.0</version>
</dependency>

编写配置类 

package com.aqiuo.factorybean;import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
//切面类。实现了MethodInterceptor方法拦截器接口
public class MyAscpect implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {check_permissions();Object object= mi.proceed();log();return object;}//增强的方法体--通知public void check_permissions() {System.out.println("模拟权限检查");}
//增强的方法体--通知public void log() {System.out.println("模拟日志记录");}}

 编写配置文件

//application.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd " > <!-- 目标类 用的是jdk的对象 --><bean id="accountService" class="com.aqiuo.service.impl.AccountServiceImpl"></bean><!-- 切面类 --><bean id="myAspect" class="com.aqiuo.aspect.MyAspect02"></bean><!-- 使用Spring工厂定义一个名称为userDaoProxy的代理对象 --><bean id="userDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean"><!-- 指定代理要实现的接口 --><property name="proxyInterfaces" value="com.aqiuo.service.AccountService"></property><!-- 指定目标对象 --><property name="target" ref="accountService"></property><!-- 指定切面,执行环绕通知 --><property name="interceptorNames" value="myAspect"></property><!-- 指定代理方式 --><property name="proxyTargetClass" value="true"></property></bean></beans>//测试

强调:获取的对象是代理之后的对象,不是原来的目标对象,获取原来的目标对象是不会有增强的 

    @Testpublic void run2() throws SQLException {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");AccountService accountService= (AccountService) applicationContext.getBean("userDaoProxy");accountService.pay(100,1,2);}

在上述代码中,首先通过bean元素定义了目标类和切面,然后使用ProxyFactoryBean类定义了代理对象。

        在定义的代理对象中,分别通过子元素指定了代理实现的接口、代理的对象、需要织入的目标类的通知,已经代理方式


 下篇文章讲解AOP的AspectJ,AspectJ是一个居于JAVA开发的AOP框架》》框架

这篇关于【Spring】AOP原来如此的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/559689

相关文章

springboot集成Lucene的详细指南

《springboot集成Lucene的详细指南》这篇文章主要为大家详细介绍了springboot集成Lucene的详细指南,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起... 目录添加依赖创建配置类创建实体类创建索引服务类创建搜索服务类创建控制器类使用示例以下是 Spring

Java调用Python的四种方法小结

《Java调用Python的四种方法小结》在现代开发中,结合不同编程语言的优势往往能达到事半功倍的效果,本文将详细介绍四种在Java中调用Python的方法,并推荐一种最常用且实用的方法,希望对大家有... 目录一、在Java类中直接执行python语句二、在Java中直接调用Python脚本三、使用Run

Java根据IP地址实现归属地获取

《Java根据IP地址实现归属地获取》Ip2region是一个离线IP地址定位库和IP定位数据管理框架,这篇文章主要为大家详细介绍了Java如何使用Ip2region实现根据IP地址获取归属地,感兴趣... 目录一、使用Ip2region离线获取1、Ip2region简介2、导包3、下编程载xdb文件4、J

浅析如何使用xstream实现javaBean与xml互转

《浅析如何使用xstream实现javaBean与xml互转》XStream是一个用于将Java对象与XML之间进行转换的库,它非常简单易用,下面将详细介绍如何使用XStream实现JavaBean与... 目录1. 引入依赖2. 定义 JavaBean3. JavaBean 转 XML4. XML 转 J

SpringBoot中四种AOP实战应用场景及代码实现

《SpringBoot中四种AOP实战应用场景及代码实现》面向切面编程(AOP)是Spring框架的核心功能之一,它通过预编译和运行期动态代理实现程序功能的统一维护,在SpringBoot应用中,AO... 目录引言场景一:日志记录与性能监控业务需求实现方案使用示例扩展:MDC实现请求跟踪场景二:权限控制与

Java NoClassDefFoundError运行时错误分析解决

《JavaNoClassDefFoundError运行时错误分析解决》在Java开发中,NoClassDefFoundError是一种常见的运行时错误,它通常表明Java虚拟机在尝试加载一个类时未能... 目录前言一、问题分析二、报错原因三、解决思路检查类路径配置检查依赖库检查类文件调试类加载器问题四、常见

Java注解之超越Javadoc的元数据利器详解

《Java注解之超越Javadoc的元数据利器详解》本文将深入探讨Java注解的定义、类型、内置注解、自定义注解、保留策略、实际应用场景及最佳实践,无论是初学者还是资深开发者,都能通过本文了解如何利用... 目录什么是注解?注解的类型内置注编程解自定义注解注解的保留策略实际用例最佳实践总结在 Java 编程

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St