Spring开发核心之AOP的实现与切入点持久化

Spring开发核心之AOP的实现与切入点持久化

什么是AOP

将一个大的功能划分为小的功能单元,然后将这些小的功能进行组合,就构成了一个完整的大功能。在划分功能单元的时候,要考虑到它们的通用性。这种技术称为模块化设计,也称为面向切面编程(AOP)

AOP的实现

Spring中AOP的实现主要是通过动态代理的方式来实现的。Spring可以为普通的类以及接口生成动态代理,以增强类的功能。

代理样例

以下面代码为例:

package com.example.demo;

public interface TestService {
    void doSomething();
}

完成代理:

package com.example.demo;

public class TestServiceProxy implements InvocationHandler {
    private Object target;

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), 
                                      target.getClass().getInterfaces(),
                                      this);
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法执行前");
        Object result = method.invoke(target, args);
        System.out.println("方法执行后");
        return result;
    }
}

在这个代理中,我们使用了代理对象和被代理的原始对象。利用这种方式,增强了原始对象的功能。

Spring AOP实现

Spring中使用AOP代理主要有两种方式:

  1. 基于proxy:使用JDK自带的Proxy类实现代理,这种方式只能代理接口,不能代理类;
  2. 基于aspect:基于Aspectj框架实现织入,可以代理接口和类。

使用proxy示例:

在Spring AOP中,我们可以通过实现Interceptor接口来实现增强方法,Interceptor有两个主要的执行方法——preHandle和afterCompletion。

假设我们有一个类:

@Service
public class TestService {
    public void doSomething() {
        System.out.println("do something!");
    }
}

为这个类添加一个拦截器:

@Aspect
@Component
public class TestAspect {
    @Pointcut("execution(* com.example.demo.TestService.*(..))")
    public void testMethod() {}

    @Before("testMethod()")
    public void doBefore() {
        System.out.println("方法执行前...");
    }

    @After("testMethod()")
    public void doAfter() {
        System.out.println("方法执行后...");
    }
}

在这个例子中,我们使用了@Aspect和@Pointcut两个注解。@Aspect表示这个类为切面类,@Pointcut表示定义一个切入点,拦截TestService类的所有方法。

使用aspect示例:

定义切面类:

@Aspect
@Component
public class AspectTest {
    @Pointcut("execution(* com.example.demo.Test.*(..))")
    public void testMethod() {}

    @Around("testMethod()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("方法执行前...");
        Object result = pjp.proceed();
        System.out.println("方法执行后...");
        return result;
    }
}

当我们使用基于aspect的方式时,我们需要定义切面类,并且使用@Aspect注解,@Pointcut注解定义需要织入的切入点,@Around注解则定义需要增强的方法。

AOP切入点持久化

在AOP中,我们经常需要使用切入点。但是,如果我们有多个切面类,而切入点又是一样的,这就会带来不必要的重复工作。所以,我们可以将一些切入点持久化,方便以后的使用。

Spring提供了两种方式来实现切入点的持久化:使用@Aspect标记或是在XML配置文件中进行定义。

@Aspect标记

  1. 定义切面接口:
package com.example.demo.advice;

public interface ICommonAdvice {
}
  1. 定义基础切面类,需要实现切面接口:
package com.example.demo.advice;

@Aspect
@Component
public abstract class BasicAdvice implements ICommonAdvice {
}

使用@Aspect标记这个类,加上@Component注解,表示这是一个切面类,并且需要实现切面接口。

  1. 在子切面类中继承并声明切入点:
package com.example.demo.advice;

@Aspect
@Component
public class TestAdvice extends BasicAdvice {
    @Pointcut("execution(* com.example.demo.Test.*(..))")
    public void testMethod() {}

    @Around("testMethod()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("方法执行前...");
        Object result = pjp.proceed();
        System.out.println("方法执行后...");
        return result;
    }
}

在子切面类中,我们可以继承父切面类,并声明自己的切入点。

XML配置

在XML配置文件中进行定义

  1. 在XML配置文件中引入AOP的命名空间
<bean xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
  1. 定义切入点:
<aop:pointcut expression="execution(* com.example.demo.Test.*(..))" id="testMethod" />
  1. 定义增强方法:
<aop:aspect ref="testAspect">
    <aop:around method="doAround" pointcut-ref="testMethod" />
</aop:aspect>

在这个例子中,我们定义了一个切入点,拦截Test类的所有方法。同时,我们定义了在Test类中应用切面的类TestAspect。我们使用标签来为 Test 添加增强方法doAround。

总结

本文介绍了AOP的实现方式及切入点的持久化方式。AOP实现主要基于动态代理,Spring中实现AOP一般有两种方式:使用@Aspect标记或是在XML文件中进行定义。切入点的持久化可以避免重复定义相同的切入点,减轻工作量,提高效率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring开发核心之AOP的实现与切入点持久化 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • 图解Spring框架的设计理念与设计模式

    图解Spring框架的设计理念与设计模式 Spring框架是Java生态中最受欢迎的开源框架之一,它利用了许多常用的设计模式和技术,用以实现IoC和AOP等特性,在Java应用程序的开发中扮演着重要的角色。 Spring框架的设计理念 Spring框架的设计理念可以用”POJO”(Plain Old Java Object)来概括,它鼓励开发者使用简单的Ja…

    Java 2023年5月19日
    00
  • java 如何读取properties文件

    Java读取properties文件步骤: 1.创建Properties对象 Properties prop = new Properties(); 2.使用load方法加载properties文件对应的输入流 InputStream in = new FileInputStream("config.properties"); prop.…

    Java 2023年5月20日
    00
  • JAVA心得分享—return语句的用法

    JAVA心得分享—return语句的用法 在Java中,return语句是非常重要的关键字之一。在这篇文章中,我将会详细讲解return语句的用法,以及一些使用return语句的最佳实践。 什么是return语句 Java中的return语句,是用于从当前方法中返回控制权并返回一个值执行方法调用的位置的命令。 返回类型 Java中return语句有两种类…

    Java 2023年5月26日
    00
  • java取某段/某个时间段的值的方法

    当我们需要从Java中的日期/时间中取出某个时间段的值时,可以使用Java中已经内置的日期/时间库来完成。 下面是取某段时间的值的方法的完整攻略: 步骤1:创建日期或时间对象 在Java中,日期和时间对象可以通过使用内置的Date,Calendar,LocalDate,LocalDateTime等类来创建。例如: Date date = new Date()…

    Java 2023年5月20日
    00
  • 如何创建线程?

    以下是关于如何创建线程的完整使用攻略: 如何创建线程? 在Java中,可以通过继承Thread类或实现Runnable接口来创建线程。以下是创建线程的步骤: 继承Thread类创建线程 创建一个继承自Thread类的子类,并重写run()方法。 java public class MyThread extends Thread { public void r…

    Java 2023年5月12日
    00
  • JSP使用MVC模式完成删除和修改功能实例详解

    我将详细讲解“JSP使用MVC模式完成删除和修改功能实例详解”的完整攻略。 什么是MVC? MVC是Model-View-Controller的缩写,它是一种设计模式,可用于在 Web 应用程序中实现代码和业务逻辑的分离。这样可以增强应用程序的可维护性、可拓展性和可重用性。 其中, Model(模型):存储应用程序的数据内容和业务逻辑。通常使用数据库实现。 …

    Java 2023年6月15日
    00
  • jsp实现简单用户7天内免登录

    实现简单用户7天内免登录,可以采用以下步骤: 添加一个cookie,保存用户信息和登录时间。当用户勾选“7天内免登录”时,在后台生成一个cookie并设置有效期为7天,将用户信息和当前时间保存到cookie中。具体实现代码如下: <% String username = request.getParameter("username"…

    Java 2023年6月15日
    00
  • Java13 明天发布(最新最全新特性解读)

    Java13 发布攻略 Java13 于 2019年9月17日发布,在这篇文档中,我们将介绍 Java13 的最新特性。 1. 新特性 以下是 Java13 中的一些新特性: 1.1 Switch 表达式 Java 13 可以使用新的关键字 yield 或 -> 来作为 switch 表达式的返回值。这使得代码更加简洁。 下面是一个例子: public…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部