Eclipse下进行基于AspectJ的AOP编程
简述
本文介绍在Eclipse下,结合Maven进行基于AspectJ的AOP编程(编译期织入)的基础知识,并给出简单的示例。 本文中使用的Eclipse版本为:3.7.1,AJDT版本为:1.6
环境准备
- 安装AspectJ Development Tools(AJDT)插件 可以到Eclipse Marketplace搜索“AJDT”,注意版本要和你的Eclipse版本匹配。或者从Update Site:http://download.eclipse.org/tools/ajdt/37/update/等位置安装,37表示Eclipse的版本为3.7。如果安装不成功,可以到AJDT网站下载离线安装包:http://www.eclipse.org/aspectj/downloads.php
- 可以使用aspectj-maven-plugin插件,让Maven支持AspectJ编译器织入。为了使用该插件,必须安装:
i):AJDT Configurator:Update Site为 http://dist.springsource.org/release/AJDT/configurator/
ii):m2e connector for build-helper-maven-plugin:到Eclipse Marketplace搜索并安装
创建AspectJ工程
安装完AJDT后重启Eclipse,即可通过File - New - AspectJ Project新建AspectJ工程了。不过最好通过Maven来创建,以提高工程的可移植性。 只需要在POM中配置aspectj-maven-plugin,然后右键 - Maven - Update Project,Eclipse工程结构即可自动生成,典型的aspectj-maven-plugin配置内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.4</version> <executions> <execution> <id>compile</id> <configuration> <XnoInline>true</XnoInline> <forceAjcCompile>true</forceAjcCompile> <showWeaveInfo>true</showWeaveInfo> <source>1.5</source> <target>1.5</target> <encoding>UTF-8</encoding> <verbose>true</verbose> <outxml>true</outxml> <aspectLibraries> <aspectLibrary> <!-- 在这里声明需要用到的切面库,这些库里面包含AspectJ切面的定义 --> <!-- 切面库同时需要作为dependency配置 --> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </aspectLibrary> </aspectLibraries> </configuration> <goals> <goal>compile</goal> <goal>test-compile</goal><!-- 如果/src/test/java下没有任何类使用了AOP,则需要去掉这一行,否则Maven执行报错(1.4版本) --> </goals> </execution> </executions> </plugin> </plugins> </build> |
应用举例
使用Spring-aspects库提供的支持,我们可以在任何类————甚至是AspectJ切面本身————上添加注解:@Configurable,每当创建该类的实例时,Spring自动对其进行依赖注入,下面是一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
package cc.gmem.demo.aop.web; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.aspectj.lang.annotation.SuppressAjWarnings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Configurable; import cc.gmem.demo.ext.ExtAjaxResult; import cc.gmem.demo.ext.ExtAjaxResultCallback; import cc.gmem.demo.ext.ExtAjaxResultTemplate; @Configurable public aspect AjaxResultAspect issingleton() { private static final Logger LOGGER = LoggerFactory.getLogger( AjaxResultAspect.class ); @Inject private ExtAjaxResultTemplate ajaxTemplate; @PostConstruct public void init() { LOGGER.debug( "AjaxResultAspect initialized." ); } public pointcut autoExtAjaxResultMarked() :@annotation(AutoExtAjaxResult); @SuppressAjWarnings Object around():autoExtAjaxResultMarked(){ return ajaxTemplate.callback( new ExtAjaxResultCallback() { public Void callback( ExtAjaxResult result ) throws Throwable { Object retVal = proceed(); result.setObject( retVal ); return VOID; } } ); } } |
上面例子编译后(Eclipse或者Maven),产生类:AjaxResultAspect.class,如果用反编译工具打开,即可看到类似下面的、由AspectJ在编译器织入到字节码的内容:
1 2 3 4 5 6 7 8 9 10 11 |
//整个static块均为织入的内容 static { ajc$preClinit(); try { LOGGER = LoggerFactory.getLogger(AjaxResultAspect.class); ajc$postClinit(); } catch (Throwable localThrowable) { ajc$initFailureCause = localThrowable; } } //构造器的代码为织入的内容,包含了进行Spring依赖注入的逻辑 public AjaxResultAspect() { JoinPoint localJoinPoint2 = Factory.makeJP(ajc$tjp_1, this, this); JoinPoint localJoinPoint1 = Factory.makeJP(ajc$tjp_0, this, this); if ((this != null) && (getClass().isAnnotationPresent(Configurable.class)) && (AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)getClass().getAnnotation(Configurable.class)))) AnnotationBeanConfigurerAspect.aspectOf().ajc$before$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$1$e854fa65(this); if (((this == null) || (!getClass().isAnnotationPresent(Configurable.class)) || (!AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)getClass().getAnnotation(Configurable.class)))) && (this != null) && (getClass().isAnnotationPresent(Configurable.class)) && (AbstractDependencyInjectionAspect.ajc$if$6f1(localJoinPoint1))) AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this); if ((!AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)getClass().getAnnotation(Configurable.class))) && (AbstractDependencyInjectionAspect.ajc$if$6f1(localJoinPoint2))) AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this); } |
Leave a Reply