spring学习历程---AOP基础
2016-11-20 12:21
323 查看
1.前置增强
Writer.javapublic interface Waiter { void greetTo(String name); void serveTo(String name); }
NativeWriter.java
public class NaiveWaiter implements Waiter { public void greetTo(String name) { System.out.println("greet to "+name+"..."); } public void serveTo(String name){ System.out.println("serving "+name+"..."); } }
GreetingBeforeAdvice.java
import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class GreetingBeforeAdvice implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object obj) throws Throwable { String clientName = (String)args[0]; System.out.println("How are you!Mr."+clientName+"."); } }TestBeforeAdvice.java
import org.springframework.aop.BeforeAdvice; import org.springframework.aop.framework.ProxyFactory; public class TestBeforeAdvice { public static void main(String[] args) { Waiter target = new NaiveWaiter(); BeforeAdvice advice = new GreetingBeforeAdvice(); ProxyFactory pf = new ProxyFactory(); pf.setInterfaces(target.getClass().getInterfaces()); pf.setOptimize(true); pf.setTarget(target); pf.addAdvice(advice); Waiter proxy = (Waiter)pf.getProxy(); proxy.greetTo("John"); proxy.serveTo("Tom"); } }beans.xml
<bean id="greetingBefore" class="com.baobaotao.advice.GreetingBeforeAdvice" /> <bean id="target" class="com.baobaotao.advice.NaiveWaiter" /> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target" p:interceptorNames="greetingAdvice"/>驱动类这样写就要使用beans.xml
public static void main(String[] args) { String configPath = "com/baobaotao/advice/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); Waiter waiter = (Waiter)ctx.getBean("waiter"); waiter.greetTo("John"); }
但测试类这样写就不必配置beans.xml
import org.springframework.aop.BeforeAdvice; import org.springframework.aop.framework.ProxyFactory; public class TestBeforeAdvice { public static void main(String[] args) { Waiter target = new NaiveWaiter(); BeforeAdvice advice = new GreetingBeforeAdvice(); ProxyFactory pf = new ProxyFactory(); pf.setInterfaces(target.getClass().getInterfaces()); pf.setOptimize(true); pf.setTarget(target); pf.addAdvice(advice); Waiter proxy = (Waiter)pf.getProxy(); proxy.greetTo("John"); proxy.serveTo("Tom"); } }
2.前置增强与后置增强
import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class GreetingAfterAdvice implements AfterReturningAdvice { public void afterReturning(Object returnObj, Method method, Object[] args, Object obj) throws Throwable { System.out.println("Please enjoy yourself!"); } }beans.xml
<bean id="greetingAfter" class="com.baobaotao.advice.GreetingAfterAdvice" /> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target" p:interceptorNames="greetingBefore,greetingAfter"/>
3.环绕增强
它结合了前置增强与后置增强GreetingInterceptor.java
public class GreetingInterceptor implements MethodInterceptor { public Object invoke(MethodInvocation invocation) throws Throwable { Object[] args = invocation.getArguments(); String clientName = (String)args[0]; System.out.println("How are you!Mr."+clientName+"."); Object obj = invocation.proceed(); System.out.println("Please enjoy yourself!"); return obj; } }beans.xml
<bean id="greetingAround" class="com.baobaotao.advice.GreetingInterceptor" /> <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean" p:proxyInterfaces="com.baobaotao.advice.Waiter" p:target-ref="target" p:interceptorNames="greetingAround" />
4.异常抛出增强
ForumService.javapublic class ForumService { public void removeForum(int forumId) { // do sth... throw new RuntimeException("运行异常。"); } public void updateForum(Forum forum) throws Exception{ // do sth... throw new SQLException("数据更新操作异常。"); } }TractionManager.java
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("成功回滚事务。"); } }ThrowsAdvice异常抛出增强接口没有定义方法,他只是一个标识接口,在运行期Spring使用反射的机制自行判断,我们必须采用以下签名形式定义异常抛出的增强方法:
void afterThrowing([Method method,Object[]args,Object target] , Throwable) ;
方法名必须为afterThrowing , 方法入参规定如下:前三个入参Method method,Object [] args ,Object target 是可选的(或者提供三个入参,或者不提供),而最后一个入参是Throwable或其子类。如:
afterThrowing(SQLException e);
afterThrowing(Method method,Object[]args , Object target ,RuntimeException e);
可以在同一个异常抛出增强中定义多个afterThrowing() , 当目标类方法抛出异常时,Spring会自动选择最匹配的增强方法。
beans.xml这样配置
<bean id="forumServiceTarget" class="com.baobaotao.advice.ForumService" /> <bean id="transactionManager" class="com.baobaotao.advice.TransactionManager" /> <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="transactionManager" p:target-ref="forumServiceTarget" p:proxyTargetClass="true"/>
5.引介增强
引介增强:比较特殊,不是在目标方法周围织入增强,而是为目标类增加新的方法和属性,属于类级别而非方法级别。public interface Monitorable { void setMonitorActive(boolean active); }
增强代码:
import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.support.DelegatingIntroductionInterceptor; public class ControllablePerformaceMonitor extends DelegatingIntroductionInterceptor implements Monitorable{ private ThreadLocal<Boolean> MonitorStatusMap = new ThreadLocal<Boolean>(); 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; } }xml配置
<bean id="pmonitor" class="com.baobaotao.introduce.ControllablePerformaceMonitor" /> <bean id="forumServiceTarget" class="com.baobaotao.introduce.ForumService" /> <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean" p:interfaces="com.baobaotao.introduce.Monitorable" p:target-ref="forumServiceTarget" p:interceptorNames="pmonitor" p:proxyTargetClass="true" /> lt;/beans>调用代码:
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestIntroduce { public static void main(String[] args) { String configPath = "com/baobaotao/introduce/beans.xml"; ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath); ForumService forumService = (ForumService)ctx.getBean("forumService"); forumService.removeForum(10); forumService.removeTopic(1022); Monitorable moniterable = (Monitorable)forumService; //监控开启 moniterable.setMonitorActive(true); forumService.removeForum(10); forumService.removeTopic(1022); } }
引介增强与之前的四类增强有较大区别,首先需要指定引介增强所实现的接口Monitorable;其次只能通过为目标类创建子类的方式生成代理,必须将p:proxyTargetClass设置成"true"
可以直观理解为下图:
相关文章推荐
- Spring学习历程 --- AOP基础之代理
- spring 学习基础笔记 包括spring 的代理 JDK CGLIB 事物 AOP 以及各种注入
- spring学习笔记(15)——AOP基础
- Spring AOP基础(Spring 3.x企业应用开发实战第六章)学习总结
- CgLib动态代理学习【Spring AOP基础之一】
- Spring基础学习教程(Spring AOP教程)-04
- spring基础学习四(aop)
- spring 学习(1.3) 入门基础- AOP 实例
- Spring基础学习(四)—AOP
- Spring学习历程---使用配置文件实现AOP
- Java动态代理学习【Spring AOP基础之一】
- Spring学习笔记(一) Spring基础IOC、AOP
- spring学习历程---spring基础总结
- spring学习小结11——AOP基础
- Spring4学习:SpringAOP基础
- [原]spring学习笔记9.1-Spring对Aop的支持-AOP基础篇
- Spring学习笔记(二)Spring基础AOP、IOC
- 学习《spring 3.x企业应用开发实战》之Spring AOP 基础
- Spring AOP基础知识学习——XML配置
- Spring基础学习教程(Spring AOP总结)-09