Spring之AOP的特性

这篇具有很好参考价值的文章主要介绍了Spring之AOP的特性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. AOP简介

AOP是Aspect-Oriented Programming的缩写,即面向切面编程。利用oop思想,可以很好的处理业务流程,但是不能把系统中某些特定的重复性行为封装到模块中。例如,在很多业务中都需要记录操作日志,结果我们不得不在业务流程中嵌入大量的日志记录代码。无论是对业务代码还是对日志记录代码来说,维护都是相当复杂的。由于系统中嵌入了这种大量的与业务无关的其他重复性代码,系统的复杂性、代码的重复性增加了。维护起来会更加复杂。

AOP可以很好解决这个问题,AOP关注的是系统的“截面”,在适当的时候“拦截”程序的执行流程,把程序的预处理和后期处理交给某个拦截器来完成。比如,访问数据库时需要记录日志,如果使用AOP的编程思想,那么在处理业务流程时不必在去考虑记录日志,而是把它交给一个专门的例子记录模块去完成。这样,程序员就可以集中精力去处理业务流程,而不是在实现业务代码时嵌入日志记录代码,实现业务代码与非业务代码的分别维护。在AOP术语中,这称为关注点分离。AOP的常见应用有日志拦截、授权认证、数据库的事务拦截和数据审计等。

当一个方法,对不同的用户的功能要求不满足时,那么需要在此方法的地方就可以出现变化;在这个变化点进行封转,留下一个可扩展的接口,便于后期的维护;
简单来说就是, 将非业务核心代码进行封装

二. AOP中的关键性概念

连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.

目标(Target):被通知(被代理)的对象
注1:完成具体的业务逻辑

通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)
注2:完成切面编程

代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),
例子:外科医生+护士
注3:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点。
(也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)

适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

在 Spring 中 AOP 代理使用 JDK 动态代理和 CGLIB 代理来实现,默认如果目标对象是接口,则使用 JDK 动态代理,否则使用 CGLIB 来生成代理类。

三. 前置通知

前置通知(org.springframework.aop.MethodBeforeAdvice):在连接点之前执行的通知()
目标接口

package com.xissl.aop.biz;

public interface IBookBiz {
	// 购书
	public boolean buy(String userName, String bookName, Double price);

	// 发表书评
	public void comment(String userName, String comments);
}

接口实现类

package com.xissl.aop.biz.impl;

import com.xissl.aop.biz.IBookBiz;
import com.xissl.aop.exception.PriceException;

public class BookBizImpl implements IBookBiz {

	public BookBizImpl() {
		super();
	}

	public boolean buy(String userName, String bookName, Double price) {
		// 通过控制台的输出方式模拟购书
		if (null == price || price <= 0) {
			throw new PriceException("book price exception");
		}
		System.out.println(userName + " buy " + bookName + ", spend " + price);
		return true;
	}

	public void comment(String userName, String comments) {
		// 通过控制台的输出方式模拟发表书评
		System.out.println(userName + " say:" + comments);
	}

}


通知

package com.xissl.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;

/**
 * 买书、评论前加系统日志
 * @author xissl
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//		在这里,可以获取到目标类的全路径及方法及方法参数,然后就可以将他们写到日志表里去
		String target = arg2.getClass().getName();
		String methodName = arg0.getName();
		String args = Arrays.toString(arg1);
		System.out.println("【前置通知:系统日志】:"+target+"."+methodName+"("+args+")被调用了");
	}

}


Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">

    <!-- aop-->
    <!-- 目标对象-->
    <bean class="com.xissl.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>
    <!-- 通知-->
    <bean class="com.xissl.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
    <!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象-->
        <property name="target" ref="bookBiz"></property>
<!--      配置代理的接口,目标对象的接口  -->
        <property name="proxyInterfaces">
            <list>
                <value>com.xissl.aop.biz.IBookBiz</value>
            </list>
        </property>
<!--        配置通知-->
        <property name="interceptorNames">
            <list>
                <value>methodBeforeAdvice</value>
            </list>
        </property>
    </bean>
</beans>

工具类org.springframework.aop.framework.ProxyFactoryBean用来创建一个代理对象,在一般情况下它需要注入以下三个属性:
proxyInterfaces:代理应该实现的接口列表(List)
interceptorNames:需要应用到目标对象上的通知Bean的名字。(List)
target:目标对象 (Object)

测试

package com.xissl.aop.demo;


import com.xissl.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo01 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//        IBookBiz bookBiz = (IBookBiz) context.getBean("bookBiz");
        IBookBiz bookBiz = (IBookBiz) context.getBean("bookProxy");
        bookBiz.buy("yhsb","《大话西游》",39.9d);
        bookBiz.comment("yhsb","尊嘟好看");
    }
}

运行结果:
Spring之AOP的特性,spring,java,后端,intellij-idea,spring boot

四. 后置通知

后置通知(org.springframework.aop.AfterReturningAdvice):在连接点正常完成后执行的通知
通知

package com.xissl.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

/**
 * 买书返利
 * @author xissl
 *
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
		String target = arg3.getClass().getName();
		String methodName = arg1.getName();
		String args = Arrays.toString(arg2);
		System.out.println("【后置通知:买书返利】:"+target+"."+methodName+"("+args+")被调用了,"+"该方法被调用后的返回值为:"+arg0);
	

	}

}


配置到Spring上下文中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">

    <!-- aop-->
    <!-- 目标对象-->
    <bean class="com.xissl.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

    <!-- 前置通知-->
    <bean class="com.xissl.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
<!--    后置通知-->
    <bean class="com.xissl.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>

    <!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象-->
        <property name="target" ref="bookBiz"></property>
<!--      配置代理的接口,目标对象的接口  -->
        <property name="proxyInterfaces">
            <list>
                <value>com.xissl.aop.biz.IBookBiz</value>
            </list>
        </property>
<!--        配置通知-->
        <property name="interceptorNames">
            <list>
                <value>methodBeforeAdvice</value><!-- 前置通知-->
                <value>myAfterReturningAdvice</value><!-- 后置通知-->
            </list>
        </property>
    </bean>
</beans>

运行结果:

Spring之AOP的特性,spring,java,后端,intellij-idea,spring boot

五. 环绕通知

环绕通知(org.aopalliance.intercept.MethodInterceptor):包围一个连接点的通知,最大特点是可以修改返回值,由于它在方法前后都加入了自己的逻辑代码,因此功能异常强大。它通过MethodInvocation.proceed()来调用目标方法(甚至可以不调用,这样目标方法就不会执行)
通知

package com.xissl.aop.advice;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 环绕通知
 * 	包含了前置和后置通知
 * 
 * @author xissl
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		String target = arg0.getThis().getClass().getName();
		String methodName = arg0.getMethod().getName();
		String args = Arrays.toString(arg0.getArguments());
		System.out.println("【环绕通知调用前:】:"+target+"."+methodName+"("+args+")被调用了");
//		arg0.proceed()就是目标对象的方法
		Object proceed = arg0.proceed();
		System.out.println("【环绕通知调用后:】:该方法被调用后的返回值为:"+proceed);
		return proceed;
	}

}


配置Spring的上下文

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">

    <!-- aop-->
    <!-- 目标对象-->
    <bean class="com.xissl.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

    <!-- 前置通知-->
    <bean class="com.xissl.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
<!--    后置通知-->
    <bean class="com.xissl.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>
<!--    环绕通知-->
    <bean class="com.xissl.aop.advice.MyMethodInterceptor" id="myMethodInterceptor"></bean>

    <!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象-->
        <property name="target" ref="bookBiz"></property>
<!--      配置代理的接口,目标对象的接口  -->
        <property name="proxyInterfaces">
            <list>
                <value>com.xissl.aop.biz.IBookBiz</value>
            </list>
        </property>
<!--        配置通知-->
        <property name="interceptorNames">
            <list>
                <value>methodBeforeAdvice</value><!-- 前置通知-->
                <value>myAfterReturningAdvice</value><!-- 后置通知-->
                <value>myMethodInterceptor</value><!-- 环绕通知-->
            </list>
        </property>
    </bean>
</beans>

运行结果:
Spring之AOP的特性,spring,java,后端,intellij-idea,spring boot

六. 异常通知

异常通知(org.springframework.aop.ThrowsAdvice):这个通知会在方法抛出异常退出时执行
通知

package com.xissl.aop.advice;

import org.springframework.aop.ThrowsAdvice;

import com.xissl.aop.exception.PriceException;

/**
 * 出现异常执行系统提示,然后进行处理。价格异常为例
 * @author xissl
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(PriceException ex) {
		System.out.println("【异常通知】:当价格发生异常,那么执行此处代码块!!!");
	}
}


Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">

    <!-- aop-->
    <!-- 目标对象-->
    <bean class="com.xissl.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

    <!-- 前置通知-->
    <bean class="com.xissl.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
<!--    后置通知-->
    <bean class="com.xissl.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>
<!--    环绕通知-->
    <bean class="com.xissl.aop.advice.MyMethodInterceptor" id="myMethodInterceptor"></bean>
<!--    异常通知-->
    <bean class="com.xissl.aop.advice.MyThrowsAdvice" id="myThrowsAdvice"></bean>

    <!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象-->
        <property name="target" ref="bookBiz"></property>
<!--      配置代理的接口,目标对象的接口  -->
        <property name="proxyInterfaces">
            <list>
                <value>com.xissl.aop.biz.IBookBiz</value>
            </list>
        </property>
<!--        配置通知-->
        <property name="interceptorNames">
            <list>
                <value>methodBeforeAdvice</value><!-- 前置通知-->
                <value>myAfterReturningAdvice</value><!-- 后置通知-->
                <value>myMethodInterceptor</value><!-- 环绕通知-->
                <value>myThrowsAdvice</value><!-- 异常通知-->
            </list>
        </property>
    </bean>
</beans>

测试

package com.xissl.aop.demo;


        import com.xissl.aop.biz.IBookBiz;
        import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Demo01 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//        IBookBiz bookBiz = (IBookBiz) context.getBean("bookBiz");
        IBookBiz bookBiz = (IBookBiz) context.getBean("bookProxy");
        bookBiz.buy("yhsb","《大话西游》",-39.9d);
        bookBiz.comment("yhsb","尊嘟好看");
    }
}

运行结果:
Spring之AOP的特性,spring,java,后端,intellij-idea,spring boot

七. 过滤通知

过滤后置通知的重复
Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       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.xsd">

    <!-- aop-->
    <!-- 目标对象-->
    <bean class="com.xissl.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

    <!-- 前置通知-->
    <bean class="com.xissl.aop.advice.MyMethodBeforeAdvice" id="methodBeforeAdvice"></bean>
<!--    后置通知-->
    <bean class="com.xissl.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>
<!--    环绕通知-->
    <bean class="com.xissl.aop.advice.MyMethodInterceptor" id="myMethodInterceptor"></bean>
<!--    异常通知-->
    <bean class="com.xissl.aop.advice.MyThrowsAdvice" id="myThrowsAdvice"></bean>
<!--    过滤通知-->
    <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="methodPointcutAdvisor">
        <property name="advice" ref="myAfterReturningAdvice"></property>
        <property name="pattern" value=".*buy"></property>
    </bean>

    <!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象-->
        <property name="target" ref="bookBiz"></property>
<!--      配置代理的接口,目标对象的接口  -->
        <property name="proxyInterfaces">
            <list>
                <value>com.xissl.aop.biz.IBookBiz</value>
            </list>
        </property>
<!--        配置通知-->
        <property name="interceptorNames">
            <list>
                <value>methodBeforeAdvice</value><!-- 前置通知-->
<!--                <value>myAfterReturningAdvice</value>&lt;!&ndash; 后置通知&ndash;&gt;-->
                <value>myMethodInterceptor</value><!-- 环绕通知-->
                <value>myThrowsAdvice</value><!-- 异常通知-->
                <value>methodPointcutAdvisor</value><!-- 过滤通知-->
            </list>
        </property>
    </bean>
</beans>

运行结果:
Spring之AOP的特性,spring,java,后端,intellij-idea,spring boot文章来源地址https://www.toymoban.com/news/detail-654776.html

到了这里,关于Spring之AOP的特性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java EE 突击 14 - Spring AOP

    这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领大家进行环境的配置 , 让大家真正用好

    2024年02月11日
    浏览(30)
  • 8.1Java EE——Spring AOP

            Spring的AOP模块是Spring框架体系中十分重要的内容,该模块一般适用于具有横切逻辑的场景,如访问控制、事务管理和性能监控等 一、AOP概述         AOP的全称是Aspect Oriented Programming,即面向切面编程。和OOP不同,AOP主张将程序中相同的业务逻辑进行横向隔离,

    2024年02月16日
    浏览(37)
  • java Sping aop 以及Spring aop 的应用事务管理

    线程死锁概念和如何避免死锁的发生: 线程的通信 wait notify() notify():---Object类 线程的状态: NEW ---start()---就绪状态---CPU时间片---运行状态 RUNNABLE]- --sleep()--- TIMED_WAITING ---wait()---- WAITING ----sysn---Blocked---- 终止状态[T] 线程池: 常见的线程池种类: 4种和原始 在软件业,AOP为Aspect Ori

    2024年02月12日
    浏览(33)
  • 【Java面试】Spring中的IOC和AOP

    IOC:控制反转也叫依赖注入。利用了工厂模式 将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的

    2024年02月10日
    浏览(36)
  • JAVA:使用 Spring AOP 实现面向切面编程

    1、简述 在现代的软件开发中,面向切面编程(AOP)是一种重要的编程范式,它允许我们将横切关注点(如日志记录、性能监控、事务管理等)从应用程序的核心业务逻辑中分离出来,以提高代码的模块化和可维护性。Spring 框架提供了强大的 AOP 支持,使得我们可以轻松地实

    2024年04月13日
    浏览(33)
  • 【Java 初级】Spring核心之面向切面编程(AOP)

    tip:作为程序员一定学习编程之道,一定要对代码的编写有追求,不能实现就完事了。我们应该让自己写的代码更加优雅,即使这会费时费力。 💕💕 推荐: 体系化学习Java(Java面试专题) AOP(面向切面编程)是一种编程范式,用于将横切关注点(如日志记录、性能统计等

    2024年02月04日
    浏览(38)
  • Java实战:Spring Boot实现AOP记录操作日志

    本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例来演示整个实现过程。本文适合已经具备Spring Boot基础

    2024年02月22日
    浏览(41)
  • 【Java学习】 Spring的基础理解 IOC、AOP以及事务

        官网: https://spring.io/projects/spring-framework#overview     官方下载工具: https://repo.spring.io/release/org/springframework/spring/     github下载: https://github.com/spring-projects/spring-framework     maven依赖: 1.spring全家桶的结构构图:              最下边的是测试单元   其中spring封装

    2024年02月09日
    浏览(29)
  • Java后端07(Spring)

    ​涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。 ​在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(sprin

    2024年02月13日
    浏览(29)
  • Linux 创建 intellij-idea快捷方式

    在 Linux 中,可以通过创建快捷方式的方式方便地打开 IntelliJ IDEA 开发工具。下面是创建 IntelliJ IDEA 快捷方式的详细步骤: 第1步:打开终端窗口 首先,要打开终端窗口。可以通过快捷键 Ctrl + Alt + T 打开终端窗口。也可以在系统菜单栏中选择“应用程序”-“实用工具”-“终端

    2024年02月03日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包