By Alex
/ in
本文介绍在Eclipse下,结合Maven进行基于AspectJ的AOP编程(编译期织入)的基础知识,并给出简单的示例。 本文中使用的Eclipse版本为:3.7.1,AJDT版本为:1.6
安装完AJDT后重启Eclipse,即可通过File - New - AspectJ Project新建AspectJ工程了。不过最好通过Maven来创建,以提高工程的可移植性。 只需要在POM中配置aspectj-maven-plugin,然后右键 - Maven - Update Project,Eclipse工程结构即可自动生成,典型的aspectj-maven-plugin配置内容如下:
<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自动对其进行依赖注入,下面是一个例子:
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在编译器织入到字节码的内容:
//整个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