Spring AOP-基于@AspectJ风格
关于Spring AOP,可以去看看官方文档:

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#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
@Aspectannotation (the @AspectJ style).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.
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.
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.
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
IsModifiedinterface, 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.
官方文档对aop一些概念的定义:
join point:在spring aop中就是指方法(你要横切的方法)。
Pointcut:join point的集合。
target Object:目标对象。
AOP proxy:代理对象。
advice:增强的逻辑以及时机(before,after等等)。
aspect:pointcut+advice,在@AspectJ风格语法中,就是一个类。下面会示例。
Introduction:spring4后提出来的概念,这里就不说了。
demo示例:
导入依赖:
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.5</version>
</dependency>
AppConfig类,加上@EnableAspectJAutoproxy注解:
@EnableAspectJAutoProxy
@ComponentScan("com.sunsas.aspectjdemo")
public class AppConfig { }
新建一个接口:
package com.sunsas.aspectjdemo.service;
public interface ProxyInterface {
void functionA();
void functionB();
}
新建一个类ProxyClassA实现接口:
package com.sunsas.aspectjdemo.service.impl; import com.sunsas.aspectjdemo.service.ProxyInterface;
import org.springframework.stereotype.Component; @Component
public class ProxyClassA implements ProxyInterface {
@Override
public void functionA() {
System.out.println("ProxyClassA functionA");
} @Override
public void functionB() {
System.out.println("ProxyClassA functionB");
}
}
在别的包下新建一个类ProxyClassB实现接口:
package com.sunsas.other; import com.sunsas.aspectjdemo.service.ProxyInterface;
import org.springframework.stereotype.Component; @Component
public class ProxyClassB implements ProxyInterface {
@Override
public void functionA() {
System.out.println("ProxyClassB functionA");
} @Override
public void functionB() {
System.out.println("ProxyClassB functionB");
}
}
声明一个切面:
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component; @Component
@Aspect
public class MyAspect {
@Pointcut("execution(* com.sunsas.aspectjdemo.service.impl.*.*(..))")
public void cutA(){
}
// @Pointcut("execution(* functionA*(..))")
// public void cutFunctionA(){
// } @Before("cutA()")
public void proxyFunctionA(){
System.out.println("++++++++++++++++++++++++begin");
System.out.println("before function");
}
// @After("cutFunctionA()")
// public void proxyFunctionB(){
// System.out.println("after function");
// System.out.println("--------------------------end");
// }
}
具体的语法可以去官方文档查看,这里使用:

表示这个service包下的所有方法都会被横切。
新建测试类Test:
package com.sunsas.aspectjdemo; import com.sunsas.aspectjdemo.service.impl.ProxyClassA;
import com.sunsas.other.ProxyClassB;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
ProxyClassA proxyClassA = (ProxyClassA) annotationConfigApplicationContext.getBean("proxyClassA");
System.out.println(proxyClassA);
ProxyClassB proxyClassB = annotationConfigApplicationContext.getBean(ProxyClassB.class);
System.out.println(proxyClassB);
proxyClassA.functionA();
proxyClassA.functionB();
proxyClassB.functionA();
proxyClassB.functionB();
}
}
项目结构如图:

运行结果为:
com.sunsas.aspectjdemo.service.impl.ProxyClassA@6c4980d3
com.sunsas.other.ProxyClassB@38b27cdc
++++++++++++++++++++++++begin
before function
ProxyClassA functionA
++++++++++++++++++++++++begin
before function
ProxyClassA functionB
ProxyClassB functionA
ProxyClassB functionB
可见ProxyClassB的方法没有被代理,因为它不在com.sunsas.aspectjdemo.service.impl下。
但如果把这个@PointCut的impl去掉:

打印结果:
com.sunsas.aspectjdemo.service.impl.ProxyClassA@1984b1f
com.sunsas.other.ProxyClassB@6d167f58
++++++++++++++++++++++++begin
before function
ProxyClassA functionA
++++++++++++++++++++++++begin
before function
ProxyClassA functionB
++++++++++++++++++++++++begin
before function
ProxyClassB functionA
++++++++++++++++++++++++begin
before function
ProxyClassB functionB
可以看到ProxyClassB的方法也被代理了。
可能是这时候接口也在此包下,所以实现了此接口的类都会被横切。
上面的MyAspect类就是一个切面,里面包括了Point cut(join point)和advice(before,after,around等等)。
Spring AOP-基于@AspectJ风格的更多相关文章
- Spring AOP 基于AspectJ
简介 AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持.因为Spring1.0的时候Aspectj还未出现; AspectJ1.5中新增了对 ...
- Spring AOP基于配置文件的面向方法的切面
Spring AOP基于配置文件的面向方法的切面 Spring AOP根据执行的时间点可以分为around.before和after几种方式. around为方法前后均执行 before为方法前执行 ...
- Spring AOP With AspectJ
一.AOP和拦截器 某些情况下,AOP和拦截器包括Filter能够实现同样的功能,一般都是请求即controller层的操作,这三个执行顺序为Filter>Interceptor>AOP, ...
- Comparing Spring AOP and AspectJ
AOP 概念 在我们开始之前 , 让我们做一个快速.高级别审查的核心术语和概念 : 方面 — —标准 / 特征代码被分散在多个场所中的应用 , 通常不同于实际的业务逻辑 (例如 , 交易管理) .各方 ...
- 比较 Spring AOP 与 AspectJ
本文翻译自博客Comparing Spring AOP and AspectJ(转载:https://juejin.im/post/5a695b3cf265da3e47449471) 介绍 如今有多个 ...
- Spring AOP 和 AspectJ
现如今有许多个可用的 AOP 库,使用这些库需要能够回答以下问题: 是否与现有的或新的应用程序兼容? 在哪里可以使用 AOP ? 如何迅速与应用程序集成? 性能开销是多少? 在本文中,我们将回答这些问 ...
- 比较分析 Spring AOP 和 AspectJ 之间的差别
面向方面的编程(AOP) 是一种编程范式,旨在通过允许横切关注点的分离,提高模块化.AOP提供方面来将跨越对象关注点模块化.虽然现在可以获得许多AOP框架,但在这里我们要区分的只有两个流行的框架:Sp ...
- Spring aop与AspectJ的区别?
根据我看spring官方文档的理解(不出意外是最正确的答案): ①选择spring的AOP还是AspectJ? spring确实有自己的AOP.功能已经基本够用了,除非你的要在接口上动态代理或者方法拦 ...
- spring aop与aspectj
AOP:面向切面编程 简介 AOP解决的问题:将核心业务代码与外围业务(日志记录.权限校验.异常处理.事务控制)代码分离出来,提高模块化,降低代码耦合度,使职责更单一. AOP应用场景: 日志记录.权 ...
- 曹工说Spring Boot源码(22)-- 你说我Spring Aop依赖AspectJ,我依赖它什么了
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
随机推荐
- Android之SimpleAdapter简单实例和SimpleAdapter参数说明
SimpleAdapter基本上认知了其参数含义 用起来就简单多了 SimpleAdapter的参数说明 第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要 第二个参数表示生 ...
- VC获取cookies的几种方法
方法一: CInternetSession::GetCookie This member function implements the behavior of the Win32 function ...
- 《Python学习手册 第五版》 -第13章 while循环和for循环
上一章已经讲过if条件语句,这章重点是循环语句:while.for 本章的重点内容 1.while循环 1)一般形式 2)break.continue.pass和循环的else 2.for循环 1)一 ...
- Go语言实现:【剑指offer】替换空格
该题目来源于牛客网<剑指offer>专题. 请实现一个函数,将一个字符串中的每个空格替换成"%20". 例如,当字符串为We Are Happy.则经过替换之后的字符串 ...
- 1.3创建你的第一个Android项目——Android第一行代码(第二版)笔记
创建HelloWorld项目 如果是第一次,会经过漫长的等待. 启动模拟器 可以用第三方模拟器,也可以用官方集成的 点击后出现如下界面,可创建多个模拟器,如图,我已经创建好了一个,如果你没有,就点击下 ...
- iOS - 一个简单的带标题的图标的实现
代码不复杂,直接上代码: ImageViewButton.h // // ImageViewButton.h// // 带有图片.底部标题或者顶部的按钮 // // #import <UIKit ...
- python 处理10000个txt,每个文件夹里面放1000个。
fileNumberInDiretory = 1000 title_list = getChongFuTitle(cursor) DiretoryNums = math.ceil(len(title_ ...
- 蓝桥杯ALGO-1,区间k大数查询
#include<stdio.h> int devide(long a[], int low, int high) { long key = a[high]; while (low< ...
- webpack性能优化
Webpack优化打包速度以及性能优化 1.跟上技术的迭代(Node.Npm.Yarn) 2.在尽可能少的模块上应用loader 3.Plugin尽可能精简并确保可靠 4.resolve参数合理配置 ...
- NCE L6