扫码关注公众号:芋道源码

发送: 百事可乐
获取永久解锁本站全部文章的链接

《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://muyinchen.github.io/2016/12/25/%E8%B0%88%20%60AOP%60%20%E7%9A%84%E9%80%9A%E4%BF%97%E7%90%86%E8%A7%A3/ 「一叶知秋」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

最近在翻译Spring Framework 5.0.0.M3中文文档 ,看到AOP时索性把自己的理解写写。 Spring的面向方面的编程(AOP),国内大都说面向切面,其实我还是觉得面向方面最恰当,何解?那就扯一扯。

1. AOP相关的概念

1) Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;

2) Join point :连接点,也就是可以进行横向切入的位置;

3) Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );

4) Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;

这就好比一团面,都是一团白面,根据食谱的不同,我们做什么样的面食即可,厨师关心的是做法,而客人关心的是色香味,再进一步的说,我同样的做面方法,完全可以用不一样的面粉(白面,玉米面,荞麦面等等),由此便可抽象出面团便是所谓的切点,而面团的加工,比如加水,放鸡蛋,放油,盐等的各种加工便是面的前置方法Before advice,将面团炸,煎,煮等做出成品来便是其后置方法After advice ,期间有所谓的环绕方法Around advice ,而客人的品评则是finally advice 中间出现问题了所造成的事件 After throwing advice 仅供理解,里面可能有不恰当的地方,但自己写代码的时注意即可,由此,这个做面的过程便是面向方面编程即所谓的一个切面(Aspect )

AOP的核心思想所在便是要求程序员专注于自己的逻辑业务,而非这团面,得以更好的去处理各种问题,从本质上进行解耦。

最后,再贴上一段代码来做参考对比:

@Aspect
@Component // for auto scan
//@Order(2)
public class LogInterceptor {
@Pointcut("execution(public * net.aazj.service..*.getUser(..))")
public void myMethod(){};
@Before("myMethod()")
public void before() {
System.out.println("method start");
}
@After("myMethod()")
public void after() {
System.out.println("method after");
}
@AfterReturning("execution(public * net.aazj.mapper..*.*(..))")
public void AfterReturning() {
System.out.println("method AfterReturning");
}
@AfterThrowing("execution(public * net.aazj.mapper..*.*(..))")
// @Around("execution(public * net.aazj.mapper..*.*(..))")
public void AfterThrowing() {
System.out.println("method AfterThrowing");
}
@Around("execution(public * net.aazj.mapper..*.*(..))")
public Object Around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("method Around");
SourceLocation sl = jp.getSourceLocation();
Object ret = jp.proceed();
System.out.println(jp.getTarget());
return ret;
}
@Before("execution(public * net.aazj.service..*.getUser(..)) && args(userId,..)")
public void before3(int userId) {
System.out.println("userId-----" + userId);
}
@Before("myMethod()")
public void before2(JoinPoint jp) {
Object[] args = jp.getArgs();
System.out.println("userId11111: " + (Integer)args[0]);
System.out.println(jp.getTarget());
System.out.println(jp.getThis());
System.out.println(jp.getSignature());
System.out.println("method start");
}
}

666. 彩蛋

如果你对 Spring 感兴趣,欢迎加入我的知识星球一起交流。

知识星球

文章目录
  1. 1. 666. 彩蛋