加载时织入(Load-Time Weaving,LTW)指的是在虚拟机载入字节码文件时动态织入AspectJ切面。Spring框架的值添加为AspectJ LTW在动态织入的过程中提供了更细粒度的控制。使用Java(5+)的代理能使用一个叫“Vanilla”的AspectJ LTW,这需要在启动JVM的时候将某个JVM参数设置为开。这种JVM范围的设置在一些情况下或许不错,但通常情况下显得有些粗颗粒。而用Spring的LTW能让你在per-ClassLoader的基础上打开LTW,这显然更加细粒度并且对“单JVM多应用”的环境更具有意义(例如在一个典型应用服务器环境中)。另外,在某些环境下,这能让你使用LTW而不对应用服务器的启动脚本做任何改动,不然则需要添加 -javaagent:path/to/aspectjweaver.jar 或者 -javaagent:path/to/Spring-agent.jar。开发人员只需要简单修改应用上下文的一个或几个文件就能使用LTW,而不需要依靠那些管理者部署配置,比如启动脚本的系统管理员。
以之前的AOP示例为基础,如果想从动态代理的方式改为静态代理的方式需要做如下的改动:(PS:此篇文章需要配合动态AOP使用示例这篇文章看)
(1)Spring全局配置文件的修改,加入LWT开关:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <aop:aspectj-autoproxy/> <context:load-time-weaver/> </beans>
(2)加入aop.xml。在class目录下的META-INF文件夹下建立aop.xml,内容如下:
<! DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> <aspectj> <weaver> <include winthin="test.*"/> </weaver> <aspects> <aspect name="test.AspectJTest"></aspect> </aspects> </aspectj>
(3)加入启动参数。
-javaagent:e:org-springframework.instrument.jar
加入后就可以进行测试了:
public static void main(String[] args){ //创建Spring上下文(加载bean.xml) ApplicationContext acx= new ClassPathXmlApplicationContext("spring-config.xml"); Hello hello = (Hello) acx.getBean("hello"); hello.test(); }
测试结果与动态AOP并无差别。
参考:《Spring源码深度解析》 郝佳 编著: