2010.01.05——spring AOP
参考:
http://electiger.blog.51cto.com/112940/129141
理解SpringAOP我们只要弄清3个对象
目标对象,切面和AOP代理
目标对象就是我们自己编写的去除了重复代码的核心类,切面则是集中了重复代码的模块,
然后在Spring的IOC中容器中以合适的方式装配起来,构成一个AOP代理,交给客户使用。
面向切面编程,针对的对象主要是类的方法。也就是说,当某个类(某些类)的某个方法(某些方法)进行
一次包装。比如,权限控制,当执行某个方法时,首先判断是否具有某种权限。
这里的包装有两个前提:1,不修改原有类的任何代码;2,用来包装的代码是易插拔的。也就是说,对于某
个方法,用于包装它的代码,可以随意地在其执行前/后执行。
三个概念:Advice,用于进行包装的类;pointcut,包装操作的切入点;Aspect,切面,一个切面应该包括
,Advice和pointcut。
四种类型:Before Advice,After Advice,Around Advice,AfterThrowingAdvice。
1.DTD方式的
DaoAdvice.java
//继承了MethodBeforeAdvice方法
public class DaoAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] args, Object obj)
throws Throwable {
String classSimpleName = obj.getClass().getSimpleName();
String className = classSimpleName.substring(0, classSimpleName.length()-3);
if(className.equals("ST_RSVRFCCH_BDao")){
CustomerContextHolder.setCustomerType("query_su9921");
System.out.println("------------ST_RSVRFCCH_BDao---------query_su9921-
----------------");
}else if(className.equals("DT_RGNCDDao")){
System.out.println("------------DT_RGNCDDao---------query-------------
----");
CustomerContextHolder.setCustomerType("query");
}
}
}
spring.xml
<aop:config proxy-target-class="false">
<aop:advisor
pointcut="execution(* com.dao.*.*(..))"//com.dao的所有方法
advice-ref="daoAdvice" />
</aop:config>
<bean id="daoAdvice" class="com.util.DaoAdvice">
</bean>
2.sping2.0 Schema的方式
当基于XML Schema实现Before Advice时,你的Advice类不用实现
org.springframework.aop.MethodBeforeAdvice接口
DaoAdvice.java
//不继承了MethodBeforeAdvice方法
public class DaoAdvice {
public void before(JoinPoint joinPoint)
{
String classSimpleName = joinPoint.getTarget().getClass().getSimpleName();
String className = classSimpleName.substring(0, classSimpleName.length()-3);
if(className.equals("ST_RSVRFCCH_BDao")){
CustomerContextHolder.setCustomerType("query_su9921");
System.out.println("------------ST_RSVRFCCH_BDao---------query_su9921-
----------------");
}else if(className.equals("DT_RGNCDDao")){
System.out.println("------------DT_RGNCDDao---------query-------------
----");
CustomerContextHolder.setCustomerType("query");
}
}
}
before方法中的JoinPoint参数是可选项,你可以根据需要决定是否需要JoinPoint参数,通过JoinPoint对象
,你可以获得目标对象(getTarget())、目标方法上的参数(getArgs())等信息。
spring.xml
<aop:config>
<aop:aspect id="testBefore" ref="daoAdvice">
<aop:before pointcut="execution(* com.dao.*.*(..))"
method="before"/>
</aop:aspect>
</aop:config>
<bean id="daoAdvice" class="com.huitu.khms.util.DaoAdvice">
</bean>
在Spring 2.0中要使用基于XML Sechma声明AOP的方式,需要在XML中加入aop的名称空间。当基于XML Sechma
实现AOP时,所有的AOP都是在<aop:config></aop:config>标签中声明的,<aop:aspect></aop:aspect>用于
定义Advice实例。<aop:before></aop:before>表示当前实例用于实现Before Advice;pointcut属性用于指
定pointcut表示式,上面的例子表示此Advice将应用于com.dao中的任何方法;method属性表示Advice上要调
用的方法。
3.基于Annotation
使用Annotation来实现Advice,在XML文件上的定义要比基于XML Sechema的方法要简便的多,但在实现
Before Advice类时,则需要使用到@Aspect、@Before标识,并需要引入org.aspectj.lang.annotation包中
的类
DaoAdvice.java
@Aspect
public class DaoAdvice {
@Before("execution(* com.huitu.khms.dao.*.*(..))" )
public void before(JoinPoint joinPoint)
{
String classSimpleName = joinPoint.getTarget().getClass().getSimpleName();
String className = classSimpleName.substring(0, classSimpleName.length()-3);
if(className.equals("ST_RSVRFCCH_BDao")){
CustomerContextHolder.setCustomerType("query_su9921");
System.out.println("------------ST_RSVRFCCH_BDao---------query_su9921-
----------------");
}else if(className.equals("DT_RGNCDDao")){
System.out.println("------------DT_RGNCDDao---------query-------------
----");
CustomerContextHolder.setCustomerType("query");
}
}
}
spring.xml
<?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"
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-2.0.xsd">
<bean id="daoAdvice" class="com.huitu.khms.util.DaoAdvice"></bean>
<aop:aspectj-autoproxy/>
</beans>
所有基于Annotation实现的Advice,在XML文件中都只要使用<aop:aspectj-autoproxy></aop:aspectj-
autoproxy>进行设置就可以了,非常简单