编译期代码生成

Nop平台的AOP机制依赖于编译期代码生成,并不是在运行期动态生成字节码。因此它要求需要预先声明哪些类会参与AOP机制,在编译时自动识别使用了这些注解的bean,然后为它们生成AOP代理类。

注意:必须先生成AOP包装类,然后NopIoC中的aop配置才能起作用

注册支持AOP机制的Annotation

在虚拟文件系统的/nop/aop/目录下增加一个后缀名为annotations的文件,在其中列举所有参与AOP处理的注解类。例如nop-api-core项目中的/_vfs/nop/aop/nop-api-core.annotations

io.nop.api.core.annotations.cache.Cache
io.nop.api.core.annotations.cache.CacheEvicts
io.nop.api.core.annotations.orm.SingleSession
io.nop.api.core.annotations.txn.TccMethod
io.nop.api.core.annotations.txn.TccTransactional
io.nop.api.core.annotations.txn.Transactional

AOP包装类生成器

GenAopProxy扫描指定工程下的target/classes目录以及target/test-classes目录,对其中的每个Java类生成aop包装类,
生成代码输出到target/generated-sources目录和target/generated-test-sources目录。

File projectDir = ...;
new GenAopProxy().execute(projectDir, generateForTestFile);

在test目录下的XXXCodeGen.java中可以增加GenAopProxy调用。

public class AuthCodeGen {
public static void main(String[] args) {
CoreInitialization.initialize();
try {
File projectDir = MavenDirHelper.projectDir(AuthCodeGen.class);
XCodeGenerator.runPrecompile(projectDir, "/", false);

new GenAopProxy().execute(projectDir, false);
new GenAopProxy().execute(projectDir, true);
} finally {
CoreInitialization.destroy();
}
}
}

通过maven工具生成AOP包装类

在pom.xml中增加exec-maven-plugin配置,为了简单一般从nop-entropy的pom.xml继承,其中已经为exec-maven-plugin配置了aop代理生成功能。

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

NopIoC配置

在beans.xml中配置Interceptor,声明它可以应用到哪些注解以及它的应用优先级。
NopIoC解析bean配置之后会检查所有的interceptor可以应用到容器中的哪些bean中,并将bean的class属性替换为对应的AOP包装类。

<bean id="nopTransactionalMethodInterceptor" ioc:default="true"
class="io.nop.dao.txn.interceptor.TransactionalMethodInterceptor">
<constructor-arg index="0" ref="nopTransactionTemplate"/>
<ioc:pointcut annotations="io.nop.api.core.annotations.txn.Transactional"
order="#{ApiConstants.INTERCEPTOR_PRIORITY_TRANSACTIONAL}"/>
</bean>