作者:海豚大叔链接:https://www.jianshu.com/p/fe8...AOP(AspectOrientProgramming)作为面向对象编程的补充,被广泛用于处理一些交叉切属性系统级服务,如事务管理、安全检查、缓存、对象池管理等。AOP实现的关键在于AOP框架自动创建的AOP代理。AOP代理可以分为两大类:静态代理和动态代理。静态代理是指用AOP框架提供的命令进行编译,这样就可以在编译阶段生成。AOP代理类,所以又叫编译时增强;而动态代理则是在运行时借助JDK动态代理、CGLIB等在内存中“临时”生成AOP动态代理类,因此也称为运行时增强。先说AspectJ。在今天之前,我认为AspectJ是Spring的一部分,因为我们一般在讲SpringAOP的时候都会提到AspectJ。事实证明,AspectJ是面向方面编程的独立解决方案。我们先抛开Spring,简单看一下AspectJ。1.AspectJ安装下载AspectJjar包,然后双击安装。安装的目录结构为:bin:存放aj、aj5、ajc、ajdoc、ajbrowser等命令,其中ajc命令最常用,其作用类似于javacdoc:存放AspectJ说明、参考手册、API文档等文件lib:该路径下的4个JAR文件是AspectJ2的核心类库,AspectJHelloWorld实现业务组件SayHelloService:packagecom.ywsc.fenfenzhong.aspectj.learn;publicclassSayHelloService{publicvoidsay(){系统输出。print("你好AspectJ");}}需要来,调用say()方法后,需要记录日志。那就是通过AspectJ的后期增强。LogAspect日志组件,实现com.ywsc.fenfenzhong.aspectj.learn.SayHelloService的后期增强:packagecom.ywsc.fenfenzhong.aspectj.learn;公共方面LogAspect{切入点logPointcut():execution(voidSayHelloService.say());after():logPointcut(){System.out.println("Logging...");}}3.编译SayHelloService,执行命令ajc-d。SayHelloService.javaLogAspect.java生成SayHelloService.class并执行命令javaSayHelloService输出HelloAspectJ日志记录。ajc.exe可以理解为javac.exe命令,用于编译Java程序。区别在于ajc.exe命令可以识别AspectJ语法;我们可以把ajc.exe看作是javac.exe命令的增强版。执行完ajc命令后的SayHelloService.class文件并不是由原来的SayHelloService.java文件编译而来的。打印日志的内容被添加到SayHelloService.class——这表明AspectJ“自动”编译了一个新类,增强了原SayHelloService.java类的功能,所以AspectJ常被称为编译时增强AOP框架。相对于AspectJ,还有另外一种AOP框架,它不需要在编译时增强目标类,而是在运行时生成目标类的代理类。代理类要么实现与目标类相同的接口,要么就是目标类。类的子类——简而言之,代理类的实例可以用作目标类的实例。一般来说,在编译时增强的AOP框架具有性能优势——因为在运行时动态增强的AOP框架在每次运行时都需要动态增强。再说说SpringAOPSpringAOP也增强了目标类,生成了代理类。但是与AspectJ最大的区别是---SpringAOP的运行时增强,而AspectJ是编译时增强。之前一直认为AspectJ是SpringAOP的一部分,因为SpringAOP使用了AspectJ的Annotation。Aspect用于定义切面,Pointcut用于定义入口点,Advice用于定义增强处理。虽然用到了Aspect的Annotation,但是并没有用到它的compiler和weaver。它的实现原理是JDK动态代理,在运行时生成代理类。为了开启Spring对@AspectJ切面配置的支持,保证Spring容器中的目标bean自动增强一个或多个切面,需要在Spring配置文件中添加如下配置
