AOP
如今的java程序世界,其他语言就不说了,面向对象是绝对的霸主地位,各种各样的复杂对象被创造出来,他们之间本身就有千丝万缕的关联,而一些源源不断的对这些对象本身的业务需求无关的需求被累加上来,会导致这些对象本身和其他对象之间的关联代码变得难以理解和分析,这时候Aop为我们提供了一种全新的视角去解决这些问题,原来我们可以在字节码层面去解决这些问题,使用动态代理的方式让java代码自己帮我们把一些无关紧要的业务需求抽离出来,这样我们既可以写纯净简单的对象代码,也可以更好的保障我们代码的安全性。
以上是我关于aop的理解,下面的是官方文档的介绍,再重温下:
aop为oop提供了另一种思考编程框架的方式,另外,oop的模块是对象,而aop的模块是面。
aop是Spring的一个关键部份,但是并不是必须的,因此可以使用aop也可以不使用,但是aop的确可以让spring的容器变得更强。
spring提供了两种使用aop的方式,即编程式aop和注解式aop,他们都是等效的。
。。
知识点
- Aspect: A modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in enterprise Java applications. In Spring AOP, aspects are implemented by using regular classes (the schema-based approach) or regular classes annotated with the
@Aspect
annotation (the @AspectJ style).
事务管理是aop的一个好的例子,在spring‘aop中一般有两种方式,一种是通过普通的java类,一种是通过@Aspect注解完成。
- Join point: A point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.
我理解为一个应用程序中可以进行切面的很多个面中的一个面,例如一组以add开始的方法名就是一个面,所以一组以addMoney开始的方法又是一个面。
- Advice: Action taken by an aspect at a particular join point. Different types of advice include “around”, “before” and “after” advice. (Advice types are discussed later.) Many AOP frameworks, including Spring, model an advice as an interceptor and maintain a chain of interceptors around the join point.
通知在spring中是作为拦截器存在的,在连接点附件维护需要的拦截器。
- Pointcut: A predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.
连接点的表达式可以匹配一个面,spring‘aop使用@AspectJ注解写表达式。
- Introduction: Declaring additional methods or fields on behalf of a type. Spring AOP lets you introduce new interfaces (and a corresponding implementation) to any advised object. For example, you could use an introduction to make a bean implement an
IsModified
interface, to simplify caching. (An introduction is known as an inter-type declaration in the AspectJ community.)
没看懂
- Target object: An object being advised by one or more aspects. Also referred to as the “advised object”. Since Spring AOP is implemented by using runtime proxies, this object is always a proxied object.
被通知的对象。
- AOP proxy: An object created by the AOP framework in order to implement the aspect contracts (advise method executions and so on). In the Spring Framework, an AOP proxy is a JDK dynamic proxy or a CGLIB proxy.
通过动态代理生成的代理对象。
- Weaving: linking aspects with other application types or objects to create an advised object. This can be done at compile time (using the AspectJ compiler, for example), load time, or at runtime. Spring AOP, like other pure Java AOP frameworks, performs weaving at runtime.
将通知内容和被代理对象合并并生成代理对象的过程称为织入,这通常在编译器完成。
能力和目标
Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans).
Spring‘aop仅支持方法作为切面切入点
Spring AOP’s approach to AOP differs from that of most other AOP frameworks. The aim is not to provide the most complete AOP implementation (although Spring AOP is quite capable). Rather, the aim is to provide a close integration between AOP implementation and Spring IoC, to help solve common problems in enterprise applications.
就是可以更好的强大ioc容器的功能,巴拉巴拉赞美之词。
@AspectJ support
@AspectJ refers to a style of declaring aspects as regular Java classes annotated with annotations. The @AspectJ style was introduced by the AspectJ project as part of the AspectJ 5 release. Spring interprets the same annotations as AspectJ 5, using a library supplied by AspectJ for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and there is no dependency on the AspectJ compiler or weaver.
@AspectJ注解的声明格式,spring‘aop只是使用这些aspectJ的注解,具体的aop实现仍然是spring’aop,如果需要使用全部的aspectJ’aop,需要做特殊处理。
Enabling @AspectJ Support
To use @AspectJ aspects in a Spring configuration, you need to enable Spring support for configuring Spring AOP based on @AspectJ aspects and auto-proxying beans based on whether or not they are advised by those aspects. By auto-proxying, we mean that, if Spring determines that a bean is advised by one or more aspects, it automatically generates a proxy for that bean to intercept method invocations and ensures that advice is executed as needed.
为了使用@AspectJ的自动织入功能,你需要去配置它,这样它可以保证被通知的对象在任何时候执行此类方法都会有代理对象去通知它。
The @AspectJ support can be enabled with XML- or Java-style configuration. In either case, you also need to ensure that AspectJ’s aspectjweaver.jar
library is on the classpath of your application (version 1.8 or later). This library is available in the lib
directory of an AspectJ distribution or from the Maven Central repository.
@AspectJ可以被配置通过xml或者java格式的形式启用,但无论哪一种aspectJweaver.jar包必须在类路径上,maven项目可以通过仓库自动引入。
Enabling @AspectJ Support with Java Configuration
To enable @AspectJ support with Java @Configuration
,
add the @EnableAspectJAutoProxy
annotation,
以上俩个注解可以开启@AspectJ注解自动编制功能。
Enabling @AspectJ Support with XML Configuration
To enable @AspectJ support with XML-based configuration, use the aop:aspectj-autoproxy
element
<aop:aspectj-autoproxy/>
Declaring a Pointcut
Declaring an Aspect
With @AspectJ support enabled, any bean defined in your application context with a class that is an @AspectJ aspect (has the @Aspect
annotation) is automatically detected by Spring and used to configure Spring AOP.
当使用上面的两种方式开始了@AspectJ形式的aop,那么任何添加了@Aspect注解的实体类将会被检测到并且被配置spring‘aop。
Aspects (classes annotated with @Aspect
) can have methods and fields, the same as any other class. They can also contain pointcut, advice, and introduction (inter-type) declarations.
@Aspect注解标志的类和其他类没有什么区别,
Access to the Current JoinPoint
Any advice method may declare, as its first parameter, a parameter of type org.aspectj.lang.JoinPoint
(note that around advice is required to declare a first parameter of type ProceedingJoinPoint
, which is a subclass of JoinPoint
. The JoinPoint
interface provides a number of useful methods:
getArgs()
: Returns the method arguments.getThis()
: Returns the proxy object.getTarget()
: Returns the target object.getSignature()
: Returns a description of the method that is being advised.toString()
: Prints a useful description of the method being advised.
Spring支持所有的通知类型,任何通知类型的第一个参数都可以是JoinPoint。需要注意的是环绕通知的第一个参数必须是ProceedingJoinPoint,这个类是JoinPoint的子类。