标签:
AOP联盟为增强定义了org.aopalliance.aop.Advice接口,Spring支持5种类型的增强:
package com.yyq.advice; public interface Waiter { void greetTo(String name); void serveTo(String name); }
NaiveWaiter服务类:
package com.yyq.advice; public class NaiveWaiter implements Waiter { @Override public void greetTo(String name) { System.out.println("greet to " + name + "..."); } @Override public void serveTo(String name) { System.out.println("serving to " + name + "..."); } }
前置增强实现类:
package com.yyq.advice; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class GreetingBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { String clientName = (String) objects[0]; System.out.println("How are you ! Mr." + clientName + "."); } }
测试方法:
@Test public void testBeforeAdvice(){ Waiter target = new NaiveWaiter(); BeforeAdvice advice = new GreetingBeforeAdvice(); ProxyFactory pf = new ProxyFactory(); //Spring提供的代理工厂 pf.setTarget(target); //设置代理目标 pf.addAdvice(advice); Waiter proxy = (Waiter)pf.getProxy(); //生成代理实例 proxy.greetTo("John"); proxy.serveTo("Tom"); }
<bean id="greetingAdvice" class="com.yyq.advice.GreetingBeforeAdvice"/> <bean id="target" class="com.yyq.advice.NaiveWaiter"/> <bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.yyq.advice.Waiter" p:interceptorNames="greetingAdvice" p:target-ref="target"/>
ProxyFactoryBean 是FactoryBean接口的实现类。
@Test public void testBeforeAdvice2(){ String configPath = "com\\yyq\\advice\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter)ctx.getBean("waiter1"); waiter.greetTo("Joe"); }
package com.yyq.advice; import org.springframework.aop.AfterReturningAdvice; import java.lang.reflect.Method; public class GreetingAfterAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object o, Method method, Object[] objects, Object o2) throws Throwable { System.out.println("Please enjoy yourself."); } }
在beans.xml文件添加后置增强:
<bean id="greetingBefore" class="com.yyq.advice.GreetingBeforeAdvice"/> <bean id="greetingAfter" class="com.yyq.advice.GreetingAfterAdvice"/> <bean id="waiter2" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.yyq.advice.Waiter" p:interceptorNames="greetingBefore,greetingAfter" p:target-ref="target"/>
测试方法:
@Test public void testBeforeAndAfterAdvice(){ String configPath = "com\\yyq\\advice\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter)ctx.getBean("waiter2"); waiter.greetTo("Joe"); }
package com.yyq.advice; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class GreetingInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { Object[] args = methodInvocation.getArguments(); String clientName = (String) args[0]; System.out.println("Hi,Mr " + clientName + "."); Object obj = methodInvocation.proceed(); System.out.println("Please enjoy yourself~"); return obj; } }
Spring 直接使用AOP联盟所定义的MethodInterceptor作为环绕增强的接口。该接口拥有唯一的接口方法 Object invoke(MethodInvocation invocation), MethodInvocation不但封装目标方法及其入参数组,还封装了目标方法所在的实例对象,通过MethodInvocation的getArguments()可以获取目标方法的入参数组,通过proceed()反射调用目标实例相应的方法。
<bean id="greetingAround" class="com.yyq.advice.GreetingInterceptor"/> <bean id="waiter3" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.yyq.advice.Waiter" p:interceptorNames="greetingAround" p:target-ref="target"/>
测试方法:
@Test public void testAroundAdvice(){ String configPath = "com\\yyq\\advice\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter)ctx.getBean("waiter3"); waiter.greetTo("Joe"); }
package com.yyq.advice; public class Forum { private int forumId; public int getForumId() { return forumId; } public void setForumId(int forumId) { this.forumId = forumId; } }
ForumService业务类:
package com.yyq.advice; import java.sql.SQLException; public class ForumService { public void removeForum(int forumId){ System.out.println("removeForum...."); throw new RuntimeException("运行异常"); } public void updateForum(Forum forum)throws Exception{ System.out.println("updateForum"); throw new SQLException("数据更新操作异常。"); } }
TransactionManager异常抛出增强实现类:
package com.yyq.advice; import org.springframework.aop.ThrowsAdvice; import java.lang.reflect.Method; public class TransactionManager implements ThrowsAdvice { public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable { System.out.println("----------------"); System.out.println("method:" + method.getName()); System.out.println("抛出异常:" + ex.getMessage()); System.out.println("成功回滚事务。"); } }
<bean id="transactionManager" class="com.yyq.advice.TransactionManager"/> <bean id="forumServiceTarget" class="com.yyq.advice.ForumService"/> <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="transactionManager" p:target-ref="forumServiceTarget" p:proxyTargetClass="true"/>
测试方法:
@Test public void testThrowsAdvice(){ String configPath = "com\\yyq\\advice\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); ForumService fs = (ForumService)ctx.getBean("forumService"); try{ fs.removeForum(10); } catch (Exception e) {} try{ fs.updateForum(new Forum()); } catch (Exception e) {} }
package com.yyq.advice; public interface Monitorable { void setMonitorActive(boolean active); }
ControllablePerformanceMonitor 为引介增强实现类:
package com.yyq.advice; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.support.DelegatingIntroductionInterceptor; public class ControllablePerformanceMonitor extends DelegatingIntroductionInterceptor implements Monitorable { private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>(); @Override public void setMonitorActive(boolean active) { MonitorStatusMap.set(active); } public Object invoke(MethodInvocation mi) throws Throwable { Object obj = null; if (MonitorStatusMap.get() != null && MonitorStatusMap.get()) { PerformanceMonitor.begin(mi.getClass().getName() + "." + mi.getMethod().getName()); obj = super.invoke(mi); PerformanceMonitor.end(); } else { obj = super.invoke(mi); } return obj; } }
PerformanceMonitor监视类:
package com.yyq.advice; public class PerformanceMonitor { private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>(); public static void begin(String method) { System.out.println("begin monitor..."); MethodPerformance mp = new MethodPerformance(method); performanceRecord.set(mp); } public static void end(){ System.out.println("end monitor..."); MethodPerformance mp = performanceRecord.get(); mp.printPerformance(); } }
MethodPerformance记录性能信息:
public class MethodPerformance { private long begin; private long end; private String serviceMethod; public MethodPerformance(String serviceMethod){ this.serviceMethod = serviceMethod; this.begin = System.currentTimeMillis(); } public void printPerformance(){ end = System.currentTimeMillis(); long elapse = end - begin; System.out.println(serviceMethod + "花费" + elapse + "毫秒。"); } }
在beans.xml文件添加引介增强:
<bean id="pmonitor" class="com.yyq.advice.ControllablePerformanceMonitor"/> <bean id="forumServiceImplTarget" class="com.yyq.advice.ForumServiceImpl"/> <bean id="forumService2" class="org.springframework.aop.framework.ProxyFactoryBean" p:interfaces="com.yyq.advice.Monitorable" p:interceptorNames="pmonitor" p:target-ref="forumServiceImplTarget" p:proxyTargetClass="true"/>
@Test public void testIntroduce(){ String configPath = "com\\yyq\\advice\\beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); ForumServiceImpl forumServiceImpl = (ForumServiceImpl)ctx.getBean("forumService2"); forumServiceImpl.removeForum(23); forumServiceImpl.removeTopic(1023); Monitorable monitorable = (Monitorable)forumServiceImpl; monitorable.setMonitorActive(true); forumServiceImpl.removeForum(22); forumServiceImpl.removeTopic(1023); }
标签:
原文地址:http://www.cnblogs.com/yangyquin/p/5463697.html