动态Aop的使用
- 创建用于拦截的bean
public class TestBean{
private String testStr = "testStr";
public String getTestStr(){
return testStr;
}
public void setTestStr(String testStr){
this.testStr = testStr;
}
public void test(){
System.out.println("test");
}
}
- 创建 Advisor
spring 使用 @AspectJ 注解对POJO进行标注,在所有的test方法执行前在控制台打印beforeTest
代码语言:javascript复制@Aspect
public class AspectJTest {
@Pointcut("execution(* *.test(...))")
public void test(){
}
@Before("test()")
public void beforeTest(){
System.out.println("beforeTest");
}
@After("test()")
public void afterTest(){
System.out.println("afterTest")
}
@Around("test()")
public Object aroundTest(ProceedingJoinPoint p){
System.out.println("before");
Object o = null;
try{
o = p.proceed();
}catch(){
}
System.out.println("after");
return o;
}
}
- 创建配置文件
<?xml version=” 1. encoding UTF 。〉
<beans xmlns=” http . //www . Springframework . org/schema/bean s ”
xmlns : xsi=” http : //www . w3 org/2001/XMLSchema - instance ”
xmlns aop http //www Springframework rg/schema/aop
xmlns · context=” http : //wwwSpringfr amework . org/schema/context ”
xsi :schemaLocation="http : //www . Spri ngframework . org/schema/beans
http : //wwwSpringframework . org/schema/beans/Spring- beans- 3 . 0 . xsd
http : //www . Springframework . org/schema/aop
http : //www . Springframework rg/schema/aop/Spring aop xsd
http : //www . Springframework . org/schema/ context
http //www Springframework org/schema/c ntext/Spring context- 3 . 0 . xsd
” >
<aop · aspect] - autoproxy />
<bean id=” test ” class=” test.TestBean ” />
<bean class= ”test.AspectJTes t ” />
</beans>
创建Aop代理
实际上 AnnotationAwareAspectJAotuProxyCreator 实现了 BeanPostProcessor 接口, 而实现 BeanPostProcessor 后,当spring加载这个Bean会在实例化前调用postProcess-AfterInitialization方法
- 获取增强器
- 获取所有的beanName , 所有beanFactory中注册的bean都会被提取出来
- 遍历beanName,找出AspectJ注解的类,进一步处理
- 对标记为AspectJ的注解进行增强器的提取.
- 将提取结果加入缓存
对获取增强器步骤的细分:
- 切点信息的获取,获得方法上的注解,将注解封装到类
- 根据切点信息生成增强,不同的增强所体现的逻辑是不同的@Before("test()"),@After("test()"),根据不同的注解类型封装不同的增强器
- 创建代理
- 获取当前类中的属性
- 添加代理接口
- 封装Advisor并加入到ProxyFactory中
- 设置要代理的类
静态Aop使用
加载时植入(Load-Time Weaving, LTW)是在虚拟机载入字节码文件时动态植入AspectJ切面. Spring 框架的值添加为 AspectJ LTW 在动态植入提供了更细粒度的控制.spring 的LTW可以让每一个类加载器打开LTW,更加细粒度
- spring 配置文件进行修改
<?xml versio 1. 0 ” encoding= ” UTF 8 ” ?>
<beans xmlns = ” http : llwww Springframework . orglschemalbeans ”
- 3 . 0 . xsd
xml ns : xsi= ” http : llwww . w3 orgl200llXMLSchema - instance "
xml ns : aop= ” http llwww . Springframework . orglschemalaop”
xmln s : context= ” http : llwww . Springfra mework . orglschema/context ”
xsi :schemaLocation= ” h ttp : l/www . Spri ngframework . org/schema/beans
http llwww Springframework orglschema/beans/Spr ng beans
http //www . Springframework . org/schema/aop
http //www Springframework org/sch臼旧/aop/Spring aop - 3 . 0 .xsd
http : //www . Springframework . org/schema/context http : //www .
Spr ngframework org/schema/conte t/Spring coηtext xsd
” ><aop : aspectj - autoproxy />
<bea id tes t ” class=” test TestBean ” />
<bean class= ” test . AspectJTest ” />
// 加入这句话
<context.load-time-weaver />
</beans>
2.加入Aop.xml 在class目录下META-INF下
代码语言:javascript复制<!DOCTYPE aspect] PUBLIC ” //AspectJ//DTD//EN””http : //www . eclipse . org/aspectj/dtd/
aspectj . dtd” >
<aspectj>
<weaver>
< 1-- only weave classes in our application- specific packages -->
<include within=” test . * ” />
</weaver>
<aspects>
<' - - weave in ] ust this aspect -->
<aspect name=” test . AspectJTest " />
</aspects>
</aspectj>
主要是告诉AspectJ对哪一个包进行植入,使用那些增强器
3.加入启动参数
代码语言:javascript复制-javaagent: path/to/Spring-agent.jar