数据库

非Spring管理Bean如何添加AOP呢?

时间:2010-12-5 17:23:32  作者:域名   来源:域名  查看:  评论:0
内容摘要:前几天有个朋友问了一个问题,觉得可以给大家分享一下。问题如下图归其根本这是个历史项目,里面有很多的类并没有交给spring管理,但现在需要统一添加日志。面对这样的问题,其实只要了解AOP的原理,就会有

 前几天有个朋友问了一个问题,添加觉得可以给大家分享一下。添加

问题如下图

归其根本这是添加个历史项目,里面有很多的添加类并没有交给spring管理,但现在需要统一添加日志。添加

面对这样的添加问题,其实只要了解AOP的添加原理,就会有多种方法。添加AOP都是添加基于动态代理来实现,而动态代理常见的添加就是cglib和java动态代理,不了解的添加可以看下之前干货君写的文章

java动态代理为什么需要基于接口 cglib动态代理对类没有任何限制吗?

但此两种方法似乎在这样的场景不好实现,需要修改大量的添加代码,那么有没有什么好的添加方案呢?

答案当然是有。

首先要清楚的添加是AOP的底层实现原理就是服务器托管字节码,我们只需要从字节码层面,添加就一定可以解决这样的问题。因此可以利用编译期增强和运行期增强,常见的方案有两种,一种Java Agent技术,另一种 AspectJ方案。

Java Agent

Java Agent中文名字叫做java 探针,可以在运行java时指定探针程序,对原程序无侵入,常见的一些APM工具都会这样,如skywalking,后续有机会给大家介绍下。如下图

java agent的主要原理就是利用JVMTI(JVM Tool Interface),JVM用来暴露一些供用户扩展的接口集合,因此可以在此处做一些运行期字节码增强。

Java Agent内容比较多,有很多大家熟悉的工具都是基于它去做的,例如阿里的arthas。源码库本文就不介绍了,后期会给大家详细介绍下Java Agent。

AspectJ方案

可以利用aspectj + javac来编译织入代码,也可以利用maven插件aspectj-maven-plugin,下面利用AspectJ注解 + aspectj-maven-plugin来实战一下。

aspectj-maven-plugin官网 http://www.mojohaus.org/aspectj-maven-plugin/usage.html

引入依赖

编译增强,依赖此jar

import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class Aop {  @Pointcut("execution(* com.ganhuojun.gracefulshutdown.controller..*.*(..))") public void pointcut1(){  } @Before("pointcut1()") public void before(){  System.out.println("controller before"); } } 

定义注解

注意:该注解不要交给spring管理

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.11</version> <configuration> <complianceLevel>1.8</complianceLevel> <source>1.8</source> <!--<showWeaveInfo>true</showWeaveInfo>--> <!--<Xlint>ignore</Xlint>--> <encoding>UTF-8</encoding> <sources> <source> <basedir>src/main/java</basedir> <!--此处使用include一致会导致织入失败,暂时未找到好的解决办法,不写则引用所有的Aspect--> <!--<includes>--> <!--<include>**/Aop.java</include>--> <!--<include>**/ControllerAop.aj</include>--> <!--</includes>--> <excludes> <exclude>**/ServiceAop.java</exclude> </excludes> </source> </sources> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> 

 配置maven插件

<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.11</version> <configuration> <complianceLevel>1.8</complianceLevel> <source>1.8</source> <!--<showWeaveInfo>true</showWeaveInfo>--> <!--<Xlint>ignore</Xlint>--> <encoding>UTF-8</encoding> <sources> <source> <basedir>src/main/java</basedir> <!--此处使用include一致会导致织入失败,暂时未找到好的解决办法,不写则引用所有的Aspect--> <!--<includes>--> <!--<include>**/Aop.java</include>--> <!--<include>**/ControllerAop.aj</include>--> <!--</includes>--> <excludes> <exclude>**/ServiceAop.java</exclude> </excludes> </source> </sources> </configuration> <executions> <execution> <goals> <goal>compile</goal> </goals> </execution> </executions> </plugin> 

 排除spring的aop

如果对spring aop比较熟悉的都知道,spring的aop也是基于AspectJ的,因此需要exclude的,已经配置到mavn的地方了。

编译&运行&测试

编译后class文件已经被织入了相关代码,如下图

运行相关日志输出如下

 说明功能已经实现。

copyright © 2025 powered by 益强资讯全景  滇ICP备2023006006号-31sitemap