通知、切点、通知者
通知
在Spring AOP里有5中类型的通知,分别由一个接口进行定义
Before(前)
|
org.springframework.aop.MethodBeforeAdvice
|
After-returning(返回后)
|
org.springframework.aop.AfterReturningAdvice
|
After-throwing(抛出后)
|
org.springframework.aop.ThrowsAdvice
|
Around(周围)
|
org.aopalliance.intercept.MethodInterceptor
|
Introduction(引入)
|
org.springframework.aop.IntroductionInterceptor
|
<bean id="audienceAdvice" class="com.springidol.AudienceAdvice"></bean>
//AudienceAdvice类实现了3中不同的3中不同类型的AOP通知。
Public class AudienceAdvice implements MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice{
//前通知要求实现的方法
public void before(Method method,Object[] args,Object target) throws Throwable{
}
//返回后通知要求实现的方法,Object returnValue表示被调用方法的返回值
public void afterReturning(Object returnValue,Method method,Object[] args,Object target) throws Throwable{
}
//抛出后通知不需要实现任何方法,它只是一个标记接口,告诉spring相应的通知要求处理被抛出的异常,除最后一个参数外,其他参数都是可选的
public void afterThrowing(Method method,Object[] args,Object target,NullPointerException e) throws Throwable{
//当发生NullPointerException 时,记录日志
LOGGER.error("NPE thrown from "+method.getName());
}
}
其中的Method method参数,表示要使用这个通知的方法,第二个参数Object[] args是方法被调用时要传递的参数。最后一个是方法调用的目标也就是被调用方法所在的对象。
//周围通知相当于前通知、后通知、抛出后通知的结合。
Public class AudienceAdvice implements MethodInterceptor{
Public Object invoke(MethodInvocation invocation) throws Throwable{
try{
.............................. //在方法调用之前
Object returnValue=invocation.proceed(); 调用目标方法
............................. //在方法调用之后
}catch(PerformanceException e){
............................. /在出现异常之后
}
}
}
切点
1.正则切点
切点的作用主要在于选择需要使用通知的方法,比如下面的正则表达式切点:
<bean id="performancePointcut" class="org.springframework.aop.support.JbkRegexpMethodPointcut">
<property name="pattern" value=".*perform" />
</bean>
Pattern属性用于制定方法匹配所使用的切点模板,本例中被设置为一个正则表达式,它应该匹配任何类里名为perform的方法。
定义切点后,把切点与通知关联
<bean id="audienceAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" value="audienceAdvice" />
<property name="pointcut" value="performancePointcut" />
</bean>
DefaultPointcutAdvisor是一个通知者类,它只是把通知关联到一个切点。
也可以使用RegexpMethodPointcutAdvisor是一个特殊的通知者类,可以在一个Bean里面定义切点和通知者
<bean id="audienceAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" value="audienceAdvice" />
<property name="pattern" value=".*perform" />
</bean>
2.定义AspectJ切点
正则表达式虽然可以作为切点定义语言来使用,但是它并不是针对切点而创建的,其主要用途还是文本解析。AspectJ里定义切点的方法就可以看出AspectJ的切点语言是一种真正的切点表达式语言。
<bean id="performancePointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
<property name="expression" value="execution(* Performer+.perform(..))" />
</bean>
可以使用DefaultPointcutAdvisor把它和通知关联起来,就像前面一样。同样,也可以设置一个特殊的通知者
<bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
<property name="advice" value="audienceAdvice" />
<property name="expression" value="execution(* *.perform(..))" />
</bean>
execution(* *.perform(..))
execution表示执行方法时,* *表示任意返回类型,.perform表示perform方法,(..)表示任意参数设置
使用ProxyFactoryBean
<bean id="duke"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>genericdaotest.dao.PersonDao</value>
</property>
<property name="target">
<bean parent="abstractDaoTarget">
<constructor-arg>
<value>genericdaotest.domain.Person</value>
</constructor-arg>
</bean>
</property>
<property name="interceptorNames">
<list>
<value>audienceAdvisor</value>
</list>
</property>
</bean>
Spring里面的ProxyFactoryBean是个工厂Bean,用于生成一个代理,把一个或者多个拦截者(和通知者)应用到Bean,有target、interceptorNames、proxyInterfaces三个属性,后两个都是数组属性target表示要代理的对象。
interceptorNames属性告诉ProxyFactoryBean哪个通知者要应用于被代理的
beanproxyInterfaces告诉ProxyFactoryBean代理应该实现哪个接口。本例中代理的是genericdaotest.dao.PersonDao接口
target告诉ProxyFactoryBean,哪个Bean是代理。
----------------以上转载自:http://bhsc.happy.blog.163.com/blog/static/1043895522008111144158773/