AspectJ AOP实现


Warning: Undefined array key "HTTP_REFERER" in /www/wwwroot/prod/www.enjoyasp.net/wp-content/plugins/google-highlight/google-hilite.php on line 58

Spring AspectJ方式提供了在代码中进行AOP的方式,宜于集中化管理PointCut,不用再写好代码后,在xml中配置一大串。
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件.

AspectJ语法

通配符

*? 表示任何数量的字符,除了.
.. 表示任何数量的字符包括任何数量的.
+? 描述指定类型的任何子类或者子接口???
!? 排除
||和&& 或,与

例:
java.*.Date???? 类型Date在任何直接的java子包中,如ava.util.Date和java.sql.Date
javax..*Model+? 所有javax包或者子包中以Model结尾的类型和其所有子类,如TableModel,TreeModel。
!vector???????????????????????????? 所有除了Vector的类型
Vector|| Hashtable????????????? Vector或者Hashtable类型
!public static * banking..*.*
所有的非public static 属性,在banking的包或者子包中
一,注解实现方式:

1,实现类
package com.lvjian.aop;

import java.util.Date;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect??? //指定下面的类为Aspect
public class Log {
Date date = new Date();
@Before(“execution( * *.update(..))”)???????? //任意类有update方法执行前执行logUpdate方法
??????????????????? //@Before(“execution( * *.update(..))”)? 前一个* 为update的返回类型,后一个 * 为类的名称
public void logUpdate(){
System.out.println( “begin update at ” + date.getTime() );
}

}

2,在applicationContext.xml像配置普通bean一样配置此类
<bean id=”logAspect”
</bean>

注:1,要在applicationContext.xml 加入对AspectJ的支持
<bean />
或<aop:aspectj-autoproxy/>

2, 注解有:
(1)Pointcut 当@Before(“execution( * *.update(..))”)? 多时,execution就会类同,这是切面,可定义一切面Pointcut解决。
???? @Pointcut(“execution( * *.update(..))”)
??????? public void pc(){???
??????????? System.out.println( “@Pointcut!!! “);??
????? }

???? @Before(value=”pc()”)
?????? public void logChange(){
?????????? System.out.println( “change!!! ” + date.getTime() );
}
(2)传统aop 增强类型有MethodBeforeAdvice,AfterReturningAdvice,MethodInterceptor,ThrowsAdvice等接口,对应的注解为:MethodBeforeAdvice? ??? @Before
??????? AfterReturningAdvice? ??? @AfterReturning
??????? MethodInterceptor????? ??? @Around
??????? ThrowsAdvice??????????? ??? @AfterThrowing
??????????????????????????????????????????????? @After :无论方法以何种方式结束,都会执行(类似于finally)
???????
?应用:
????
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Log {
Date date = new Date();
@Before(“execution( * *.update(..))”)
public void logUpdate(){
System.out.println( “begin update at ” + date.getTime() );
}

@Pointcut(“execution( * *.update(..))”)
public void pc(){???
System.out.println( “@Pointcut!!! “);

}

@Before(value=”pc()”)
public void logChange(){
System.out.println( “before change!!! “? );
}

@AfterReturning(value=”pc()”)
public void AfterlogChange(){
System.out.println( “after!!! “? );
}

@Around(value=”pc()”)
public Object AroundlogChange( ProceedingJoinPoint point ) throws Throwable{
System.out.println( “around before “? );
Object re = point.proceed();
System.out.println( “around after “? );
return re;
}

@After(value=”pc()”)
public void AfterlogChange() {
System.out.println( “After ?? finally “? );
}
}
(3)注解对监听方法的操作:
1) 在形参中定义org.aspectj.lang.JoinPoint类型的参数,用些来访问方法。(注:@Around 用的是是ProceedingJoinPoint,它是org.aspectj.lang.JoinPoint的一个子类)
???
??? JoinPoint 方法有:
????? getArgs() :?? 返回方法形参
????? getThis() :?? 返回代理对象
????? getTarget() :返回目标
????? getSignature() :返回正在被通知的方法相关信息
????? toString() : 打印出正在被通知的方法的有用信息
@Before(value=”pc()”)
public void logChange( JoinPoint jp ){

System.out.println( “toString? ” + jp.toString()? );
}

2) 获取方法的参数
? getArgs() :?? 返回方法形参

? @AfterReturning(“execution( * *.admin(..))&&args(userName,..)”)?? //args与类平行
? public void AfterReturninglogAdmin( String userName ){
????? System.out.println( “after admin !!! ” + userName );
}
二,XML配置实现方式:
1, 修改xml的头部,让其支持aop命名空间。
<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
xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
??????????????? http://www.springframework.org/schema/aop
??????????????? http://www.springframework.org/schema/aop/spring-aop.xsd“>

2,在XML中配置:
<aop:config>

<aop:aspect id=”log” ref=”logXML”>
<aop:pointcut id=”update” expression=”execution( * *.XMLBefore())” />
<aop:before pointcut-ref=”update”? method=”logUpdate” />
</aop:aspect>

</aop:config>

注: 要去掉用传统方式实现的自动代理AutoProxyCreator 如:
<bean id=”autoPghroxyCreator”?>
</bean>