Spring AOP

本篇文章翻译自AOP with Spring,主要介绍是关于AOP的概念。

Brief introduction (简介)

One of the key components of Spring Framework is the Aspect oriented programming (AOP) framework. Aspect-Oriented Programming entails breaking down program logic into distinct parts called so-called concerns. The functions that span multiple points of an application are called cross-cutting concerns and these cross-cutting concerns are conceptually separate from the application’s business logic. There are various common good examples of aspects like logging, auditing, declarative transactions, security, caching, etc.

The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Dependency Injection helps you decouple your application objects from each other and AOP helps you decouple cross-cutting concerns from the objects that they affect. AOP is like triggers in programming languages such as Perl, .NET, Java, and others.

Spring AOP module provides interceptors to intercept an application. For example, when a method is executed, you can add extra functionality before or after the method execution.

翻译:

AOP面向切面编程是Spring框架中的最关键的部分之一。面向切面编程需要拆分程序逻辑到被称为关注点的不同部分。一个在应用程序内跨越多个点的方法被称为横切点,这些横切点和应用的业务逻辑在概念上是分开的。目前已经有很多应用切面的例子,比如日志,审计,声明式事务,安全,缓存等。

在面向对象编程中,模块化的关键单元是类,但是在面向切面编程中,模块化单元是切面。依赖注入帮助你将应用中的对象相互解耦,AOP帮助你将横切点从它们作用的对象中解耦。AOP就像是Perl,.NET,Java或者其他编程语言中的触发器。

Spring AOP模块提供拦截应用的拦截器。举个🌰,你可以在你运行的方法之前或者之后添加额外的功能或者方法。

AOP Terminologies(AOP 术语)

Aspect(切面)

This is a module which has a set of APIs providing cross-cutting requirements. For example, a logging module would be called AOP aspect for logging. An application can have any number of aspects depending on the requirement.

翻译: Aspect一个提供横切(cross-cutting)APIs的模块。举个例子,日志模块被称为AOP 日志切面。一个应用可以根据需求拥有任何数量的切面。

Join point(连接点)

This represents a point in your application where you can plug-in the AOP aspect. You can also say, it is the actual place in the application where an action will be taken using Spring AOP framework.

翻译: 在应用中可以插入AOP切面的地方可被抽象为一个点。你也可以说,这是一个在应用中存在的地方,这个地方将被Spring AOP 框架执行一些动作。

Advice(通知)

This is the actual action to be taken either before or after the method execution. This is an actual piece of code that is invoked during the program execution by Spring AOP framework.

翻译:Advice是一个实际的动作,它将在方法执行前和方法执行后执行。这段代码通过Spring AOP框架在程序运行时被调用。

Pointcut(切入点)

This is a set of one or more join points where an advice should be executed. You can specify pointcuts using expressions or patterns as we will see in our AOP examples.

翻译:Pointcut是一个或者多个连接点的集合。正如我们将在AOP例子中看到的,你可以使用表达式或者正则表达式制定你的切入点。

Introduction(引入)

An introduction allows you to add new methods or attributes to the existing classes.

翻译:引入可以允许你添加新的方法或者属性到已经存在的类中。

Target object

The object being advised by one or more aspects. This object will always be a proxied object, also referred to as the advised object.

翻译:这个对象被一个或者多个切面通知。这个对象一般是代理对象,作为被通知对象引用。

Weaving(织入)

Weaving is the process of linking aspects with other application types or objects to create an advised object. This can be done at compile time, load time, or at runtime.

翻译:织入是链接切面和其他应用类型或者对象来创建通知对象的过程。这个过程可以在编译、加载或者执行期间进行。

Types of Advice

Spring aspects can work with five kinds of advice mentioned as follows.
翻译:Spring 切面可以使用如下提到的五种advice

  • before: Run advice before a method execution.

  • after: Run advice after a method execution.

  • after-returning: Run advice after the a method execution only if method completes successfully.

  • after-throwing: Run advice after the method execution only if method exits by throwing an exception.

  • around: Run advice before and after the advised method is invoked.

Custom Aspects Implementation(自定义接口实现)

XML Schema based(基于XML模式)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

<?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"
xmlns:tx="http:www.springframework.org/schema/tx"
xsi:schemaLocation="http:www.springframework.org/schema/beans
http:www.springframework.org/schema/beans/spring-beans-4.2.xsd
http:www.springframework.org/schema/aop
http:www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 业务逻辑类--AOP连接点 -->
<bean id="aopTest" class="com.zhongyp.zen.service.aop.AOPTestService" />
<!--AOP切面-->
<bean id="timeHandler" class="com.zhongyp.zen.service.handler.TimeHandler" />
<!--AOP切面-->
<bean id="printHandler" class="com.zhongyp.zen.service.handler.PrintHandler"></bean>

<aop:aspectj-autoproxy />
<aop:config>
<!-- pointcut切入点(AOP连接点的集合)-->
<aop:pointcut id="pointcut" expression="execution(* com.zhongyp.zen.service.*.*.*(..))" />
<!-- 切面 -->
<aop:aspect id="time" ref="timeHandler">
<!-- AOP Advice -->
<aop:before method="printStartTime" pointcut-ref="pointcut" />
<aop:after method="printEndTime" pointcut-ref="pointcut" />
</aop:aspect>
<aop:aspect id="print" ref="printHandler">
<aop:after-returning method="printString" pointcut-ref="pointcut"></aop:after-returning>
</aop:aspect>
</aop:config>
</beans>

@AspectJ based(基于切面注解)

注解方式可以将上述xml配置以注解的形式配置一下,我这里只是给出一个样例,其他的还需读者自己实践。

1
2
3
4
5
6
7
8
9
10
11
12
@Aspect
@Component("logHandler")
public class LogHandler {
@Pointcut("execution(* com.zhongyp.zen.service.*.*.*(..))")
private void hehe(){

}
@Before("hehe()")
public void doBefore(){
System.out.println("为毛国庆要加班!!!!");
}
}