浅谈spring——增强接口(六)

来源:互联网 发布:与制工作室长板淘宝 编辑:程序博客网 时间:2024/06/07 09:31

AOP支持5种类型的增强。


增强接口关系图:


1)前置增强:BeforeAdvice,表示在目标方法执行前实施增强。

2)后置增强:AfterReturningAdvice,表示在目标方法执行后实施增强。

3)环绕增强:MethodInterceptor,表示在目标方法执行前后实施增强

4)异常增强:ThrowsAdvice,表示在目标方法抛出异常后实施增强

5)引介增强:IntroductionInterceptor,表示在目标类中添加一些新的属性和方法


xml配置:

[html] view plaincopyprint?
  1. <bean id="greetingBefore" class="com.baobaotao.advice.GreetingBeforeAdvice" />  
  2. <bean id="target" class="com.baobaotao.advice.NaiveWaiter" />  
  3. <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"  
  4.     p:proxyInterfaces="com.baobaotao.advice.Waiter"   ##代理接口  
  5.     p:target-ref="target"  ##指定对哪个bean增强  
  6.     p:interceptorNames="greetingBefore"/>    ##指定的增强  

代码实例

1)前置增强:

[html] view plaincopyprint?
  1. import java.lang.reflect.Method;  
  2.   
  3. import org.springframework.aop.MethodBeforeAdvice;  
  4.   
  5. public class GreetingBeforeAdvice implements MethodBeforeAdvice {  
  6.     public void before(Method method, Object[] args, Object obj) throws Throwable {  
  7.         String clientName = (String)args[0];  
  8.         System.out.println("How are you!Mr."+clientName+".");  
  9.     }  
  10. }  

method:目标类的方法

args:目标类方法的入参

obj:目标类实例


2)后置增强:

[html] view plaincopyprint?
  1. import java.lang.reflect.Method;  
  2. import org.springframework.aop.AfterReturningAdvice;  
  3.   
  4. public class GreetingAfterAdvice implements AfterReturningAdvice {  
  5.   
  6.     public void afterReturning(Object returnObj, Method method, Object[] args,  
  7.             Object obj) throws Throwable {  
  8.         System.out.println("Please enjoy yourself!");  
  9.     }  
  10. }  
returnObj:目标实例方法返回的结果

method:目标类方法

args:目标实例方法的入参

obj:目标类实例


3)环绕增强

[html] view plaincopyprint?
  1. import org.aopalliance.intercept.MethodInterceptor;  
  2. import org.aopalliance.intercept.MethodInvocation;  
  3.   
  4. public class GreetingInterceptor implements MethodInterceptor {  
  5.   
  6.     public Object invoke(MethodInvocation invocation) throws Throwable {  
  7.         Object[] args = invocation.getArguments();//获取入参  
  8.         String clientName = (String)args[0];  
  9.         System.out.println("How are you!Mr."+clientName+".");  
  10.           
  11.         Object obj = invocation.proceed();//反射机制调用目标方法  
  12.           
  13.         System.out.println("Please enjoy yourself!");  
  14.           
  15.         return obj;  
  16.     }  
  17. }  
MethodInvocation不但封装了目标方法及其入参数组,还封装了目标方法所在的实例对象


4)抛出异常的增强

[html] view plaincopyprint?
  1. import java.lang.reflect.Method;  
  2.   
  3. import org.springframework.aop.ThrowsAdvice;  
  4.   
  5. public class TransactionManager implements ThrowsAdvice {  
  6.     public void afterThrowing(Method method, Object[] args, Object target,  
  7.             Exception ex) throws Throwable {  
  8.         System.out.println("-----------");  
  9.         System.out.println("method:" + method.getName());  
  10.         System.out.println("抛出异常:" + ex.getMessage());  
  11.         System.out.println("成功回滚事务。");  
  12.     }  
  13. }  
ThrowAdvice异常抛出增强接口没有定义任何方法,它是一个标识接口,在运行时由spring使用反射机制自行判断。

method:目标类方法

args:目标实例方法的入参

target:目标类实例

ex:要捕获的异常

其中前三个参数可以缺省。afterThrowing方法,可以定义多个,当目标方法抛出异常时,spring会自动找出最匹配的增强方法。


5)引介增强:比较特殊,不是在目标方法周围织入增强,而是为目标类增加新的方法和属性,属于类级别而非方法级别。

接口

[html] view plaincopyprint?
  1. public interface Monitorable {  
  2.    void setMonitorActive(boolean active);  
  3. }  


增强代码

[html] view plaincopyprint?
  1. import org.aopalliance.intercept.MethodInvocation;  
  2. import org.springframework.aop.support.DelegatingIntroductionInterceptor;  
  3. public class ControllablePerformaceMonitor extends  
  4.             DelegatingIntroductionInterceptor implements Monitorable{  
  5.               
  6.     private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>();  
  7.     public void setMonitorActive(boolean active) {  
  8.         MonitorStatusMap.set(active);  
  9.     }  
  10.     public Object invoke(MethodInvocation mi) throws Throwable {  
  11.         Object obj = null;  
  12.         if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) {  
  13.             PerformanceMonitor.begin(mi.getClass().getName() + "."  
  14.                     + mi.getMethod().getName());  
  15.             obj = super.invoke(mi);  
  16.             PerformanceMonitor.end();  
  17.         } else {  
  18.             obj = super.invoke(mi);  
  19.         }  
  20.         return obj;  
  21.     }  
  22.   
  23. }  

xml配置

[html] view plaincopyprint?
  1. <bean id="pmonitor" class="com.baobaotao.introduce.ControllablePerformaceMonitor" />  
  2. <bean id="forumServiceTarget" class="com.baobaotao.introduce.ForumService" />  
  3. <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"  
  4.     p:interfaces="com.baobaotao.introduce.Monitorable"   
  5.     p:target-ref="forumServiceTarget"  
  6.     p:interceptorNames="pmonitor"   
  7.     p:proxyTargetClass="true" />  
  8. lt;/beans>  

调用代码

[html] view plaincopyprint?
  1. import org.springframework.context.ApplicationContext;  
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  3.   
  4.   
  5. public class TestIntroduce {  
  6.     public static void main(String[] args) {  
  7.         String configPath = "com/baobaotao/introduce/beans.xml";  
  8.         ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);  
  9.         ForumService forumService = (ForumService)ctx.getBean("forumService");  
  10.         forumService.removeForum(10);  
  11.         forumService.removeTopic(1022);  
  12.           
  13.         Monitorable moniterable = (Monitorable)forumService;   //监控开启  
  14.         moniterable.setMonitorActive(true);  
  15.         forumService.removeForum(10);  
  16.         forumService.removeTopic(1022);   
  17.     }  
  18. }  

引介增强与之前的四类增强有较大区别,首先需要指定引介增强所实现的接口Monitorable;其次只能通过为目标类创建子类的方式生成代理,必须将p:proxyTargetClass设置成"true"

可以直观理解为下图:


0 0
原创粉丝点击