写点什么

一文彻底帮你打通 SpringAOP 的任督二脉,大厂高薪指日可待,建议收藏!!!

  • 2021 年 11 月 11 日
  • 本文字数:1682 字

    阅读完需:约 6 分钟

1.AOP 案例




我们通过日志的案例来给大家来介绍,先看下我们不使用 AOP 的情况下来实现日志记录方法执行的时间。

1.1 非 AOP 实现

首先创建一个 SpringBoot 项目,然后创建 IUserService 接口,定义如下:


public interface IUserService {


pu


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


blic void log1();


public void log2();


}


然后创建接口的实现,如下:


@Service


public class UserServiceImpl implements IUserService {


@Override


public void log1() {


long start = System.currentTimeMillis();


try {


Thread.sleep(5);


System.out.println("log1 方法执行了 ...");


} catch (InterruptedException e) {


e.printStackTrace();


}


long end = System.currentTimeMillis();


System.out.println("log1 方法执行耗时:" + (end - start));


}


@Override


public void log2() {


try {


Thread.sleep(5);


System.out.println("log2 方法执行了 ...");


} catch (InterruptedException e) {


e.printStackTrace();


}


}


}


测试代码


//@SpringBootApplication


@Configuration


@ComponentScan


public class SpringAopDemo02Application {


public static void main(String[] args) {


//SpringApplication.run(SpringAopDemo02Application.class, args);


ApplicationContext ac = new AnnotationConfigApplicationContext(SpringAopDemo02Application.class);


IUserService bean = ac.getBean(IUserService.class);


bean.log1();


}


}



到这儿我们可以看出在 Service 中我们的核心业务代码和日志模块的代理耦合在了一块,这显然是不合适的,这时 AOP 就派上用场了。

1.2 AOP 实现

Spring 中的 AOP 的实现有多种方式,本文就不具体的来一一介绍了,感兴趣的可以参考本人的另一篇文章


https://blog.csdn.net/qq_38526573/article/details/86441916


本文重点介绍原理,我们需要先添加 AspectJ 的依赖


<dependency>


<groupId>org.springframework</groupId>


<artifactId>spring-aspects</artifactId>


</dependency>


然后定义切面类


@Aspect


@Component


public class MyAspect {


/**


  • 定义一个环绕通知

  • @param pjp

  • @return


*/


@Around("execution(* com.bobo.service.impl.*.log2(..))")


public Object around(ProceedingJoinPoint pjp){


long start = System.currentTimeMillis();


Object proceed = null;


try {


// 执行目标对象的方法


proceed = pjp.proceed();


} catch (Throwable throwable) {


throwable.printStackTrace();


}


long end = System.currentTimeMillis();


System.out.println(pjp.getSignature().getName() + " 执行耗时:" + (end - start));


return proceed;


}


}


然后我们在需要添加@EnableAspectJAutoProxy注解来放开代理的使用


//@SpringBootApplication


@Configuration


@ComponentScan


@EnableAspectJAutoProxy


public class SpringAopDemo02Application {


public static void main(String[] args) {


//SpringApplication.run(SpringAopDemo02Application.class, args);


ApplicationContext ac = new AnnotationConfigApplicationContext(SpringAopDemo02Application.class);


IUserService bean = ac.getBean(IUserService.class);


bean.log1();


System.out.println("-------------------");


bean.log2();


}


}


通过输入我们发现代理生效了



通过上面的操作你会发现 SpringAOP 的实现还是比较简单的,也实现了业务代码和系统功能的分离。更利于系统的扩展。


2.AOP 原理分析




上面的案例实现了 AOP,接下来我们需要分析下 AOP 的原理,前面介绍了代理模式,我们知道代理模式的实现方式有多种,首先我们来看看 AOP 是采用的 JDK 代理还是 CGLIB 代理呢?

2.1 AOP 的本质

其实在 Spring 的 AOP 中既有 JDK 代理的实现也有 CGLIB 的使用,为什么这么说呢?我们通过演示带大家看看。首先在前面的测试案例的基础上我们通过 debug 模式来看



通过断点我们发现 IUserService 的 bean 对象是一个 JDK 动态代理的对象。那 CGLIB 代理呢?我们这样来做。定义一个 PersonServiceImpl 这个 Service 没有实现任何的接口


@Service


public class PersonServiceImpl {


public void show(){


System.out.println("Hello ...");


}


}

评论

发布
暂无评论
一文彻底帮你打通SpringAOP的任督二脉,大厂高薪指日可待,建议收藏!!!