Spring中实现AOP的三种方式

简介: Spring中实现AOP的三种方式

1、什么是AOP

AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 面向方面的编程(AOP)是一种新的编程技术,它弥补了面向对象的编程(OOP)在跨越模块行为上的不足。AOP 引进了 Aspect,它将影响多个类的行为封装到一个可重用模块中,它允许程序员对横切关注点进行模块化,从而消除了 OOP 引起的代码混乱和分散问题,增强了系统的可维护性和代码的重用性

2、AOP在Spring中的作用

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

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

即 Aop 在 不改变原有代码的情况下 , 去增加新的功能 .

3、使用Spring实现Aop

准备工作:需要导入一个依赖包:

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

第一种实现方式:

通过Spring API实现,编写业务接口和实现类

public interface UserService {
    /**
     * 增加
     */
    void add();
}
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("执行了add方法");
    }
}

编写增强类,一个前置,一个后置

public class Log implements MethodBeforeAdvice {
    /**
     * target:目标对象
     * args:参数
     * method:目标对象的方法
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"执行了"+method.getName()+"方法");
    }
}
public class AfterLog implements AfterReturningAdvice {
    /**
     * returnValue:返回值
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("执行了"+method.getName()+"方法,返回结果"+returnValue);
    }
}

编写配置文件,注意导入aop约束

<?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-->
    <bean id="userService" class="com.lili.service.UserServiceImpl"/>
    <bean id="log" class="com.lili.log.Log"/>
    <bean id="afterLog" class="com.lili.log.AfterLog"/>
    <!--方式一:使用原生Spring API接口 -->
    <!--配置aop:需要导入aop的约束-->
        <aop:config>
        <!--切入点:expression:表达式,execution(要执行的位置! * * * * *) -->
        <aop:pointcut id="pointcut" expression="execution(* com.lili.service.UserServiceImpl.*(..))"/>
        <!--执行环绕增加!-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
        </aop:config>
</beans>

测试:

@Test
    public void test1(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }

输出:

com.lili.service.UserServiceImpl执行了add方法
执行了add方法
执行了add方法,返回结果null

第二种方式:

自定义类来实现AOP

编写植入类

public class OneSelfPointcut {
    public void before() {
        System.out.println("使用前");
    }
    public void after() {
        System.out.println("使用后");
    }
}

编写配置:

<beans>
<!--方式二:自定义类-->
        <bean id="oneSelfPointcut" class="com.lili.onself.OneSelfPointcut"/>
        <aop:config>
        <!--自定义切面, ref 要引用的类-->
        <aop:aspect ref="oneSelfPointcut">
        <!--切入点-->
        <aop:pointcut id="point" expression="execution(* com.lili.service.UserServiceImpl.*(..))"/>
        <!--通知-->
        <aop:before method="before" pointcut-ref="point"/>
        <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
        </aop:config>
</beans>

运行:

使用前
执行了add方法
使用后

第三种方式:

使用注解来实现AOP

编写使用注解实现的类

@Aspect// 标注此类是一个切面
public class AnnotationPointCut {
    @Before("execution(* com.lili.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("方法执行前");
    }
    @After("execution(* com.lili.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("方法执行后");
    }
}

编写配置:

<!--方式三-->
    <bean id="annotationPointCut" class="com.lili.onself.AnnotationPointCut"/>
    <!--开启注解支持!   JDK(默认 proxy-target-class="false")   cglib(proxy-target-class="true")-->
    <aop:aspectj-autoproxy/>

运行:

方法执行前
执行了add方法
方法执行后


目录
相关文章
|
2月前
|
Java
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
这篇文章是Spring5框架的实战教程,深入讲解了AOP的基本概念、如何利用动态代理实现AOP,特别是通过JDK动态代理机制在不修改源代码的情况下为业务逻辑添加新功能,降低代码耦合度,并通过具体代码示例演示了JDK动态代理的实现过程。
Spring5入门到实战------9、AOP基本概念、底层原理、JDK动态代理实现
|
14天前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
3月前
|
Java Spring
在Spring Boot中使用AOP实现日志切面
在Spring Boot中使用AOP实现日志切面
|
4天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
35 9
|
27天前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
2月前
|
XML Java 数据格式
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
2月前
|
缓存 Java 开发者
Spring高手之路22——AOP切面类的封装与解析
本篇文章深入解析了Spring AOP的工作机制,包括Advisor和TargetSource的构建与作用。通过详尽的源码分析和实际案例,帮助开发者全面理解AOP的核心技术,提升在实际项目中的应用能力。
28 0
Spring高手之路22——AOP切面类的封装与解析
|
2月前
|
安全 Java 开发者
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
Java 新手入门:Spring 两大利器IoC 和 AOP,小白也能轻松理解!
31 1
|
2月前
|
Java Spring
Spring的AOP组件详解
该文章主要介绍了Spring AOP(面向切面编程)组件的实现原理,包括Spring AOP的基础概念、动态代理模式、AOP组件的实现以及Spring选择JDK动态代理或CGLIB动态代理的依据。
Spring的AOP组件详解
|
2月前
|
Java API Spring
Spring Boot 中的 AOP 处理
对 Spring Boot 中的切面 AOP 做了详细的讲解,主要介绍了 Spring Boot 中 AOP 的引入,常用注解的使用,参数的使用,以及常用 api 的介绍。AOP 在实际项目中很有用,对切面方法执行前后都可以根据具体的业务,做相应的预处理或者增强处理,同时也可以用作异常捕获处理,可以根据具体业务场景,合理去使用 AOP。