Spring中Aop的实现方式之一(基于动态代理)
2016-04-27 16:09
661 查看
Spring中重要的概念:基于AOP切面编程:(其实就是在方法的前后加入执行代码)
切面:Aspect:即由切入点(PointCut)和通知(Advice)
切入点:就是需要加入切面代码的地点(通常是某个方法名称,实际中用正则来匹配)。
通知:就是切入点发生后要做的事情,比如执行某段代码。
首先Spring支持5中通知:
(1)Before(前) org.apringframework.aop.MethodBeforeAdvice
(2)After-returning(返回后) org.springframework.aop.AfterReturningAdvice
(3)After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
(4)Arround(周围) org.aopaliance.intercept.MethodInterceptor
(5)Introduction(引入) org.springframework.aop.IntroductionInterceptor
可以看出都是对某个方法进行通知(也证实了AOP的实际含义就是在某个方法前后加入代码段的概念)
先首先用代理模式怎么实现AOP
(1)创建通知:实现这几个接口,把其中的方法实现了
(2)创建切入点:一般通过正则匹配
(3)定义切面(把通知和切入点整合):常用的切面类有:
NameMatchMethodPointcutAdvisor,JdkRegexpMethodPointcut, DefaultPointcutAdvisor
(4)使用ProxyFactoryBean来生成代理,需指定要代理的接口和实现类,并把切面配置进去
具体:
1、先定义一个通知:用Arround
3、定义一个切面:(这里用DefaultPointcutAdvisor)
最后要在代理中配置
4、测试下:
例如: NameMatchMethodPointcutAdvisor
上面的配置就可以这样配置了:
只是把切入点的配置换成了mappedName而已,因为里面封装了mappedName为切入点:
切面:Aspect:即由切入点(PointCut)和通知(Advice)
切入点:就是需要加入切面代码的地点(通常是某个方法名称,实际中用正则来匹配)。
通知:就是切入点发生后要做的事情,比如执行某段代码。
首先Spring支持5中通知:
(1)Before(前) org.apringframework.aop.MethodBeforeAdvice
(2)After-returning(返回后) org.springframework.aop.AfterReturningAdvice
(3)After-throwing(抛出后) org.springframework.aop.ThrowsAdvice
(4)Arround(周围) org.aopaliance.intercept.MethodInterceptor
(5)Introduction(引入) org.springframework.aop.IntroductionInterceptor
可以看出都是对某个方法进行通知(也证实了AOP的实际含义就是在某个方法前后加入代码段的概念)
先首先用代理模式怎么实现AOP
(1)创建通知:实现这几个接口,把其中的方法实现了
(2)创建切入点:一般通过正则匹配
(3)定义切面(把通知和切入点整合):常用的切面类有:
NameMatchMethodPointcutAdvisor,JdkRegexpMethodPointcut, DefaultPointcutAdvisor
(4)使用ProxyFactoryBean来生成代理,需指定要代理的接口和实现类,并把切面配置进去
具体:
1、先定义一个通知:用Arround
public class MethodAroundInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation arg0) throws Throwable { System.out.println("Method around before " + arg0.getMethod().getName()); arg0.proceed(); //是否要调用切面代码 System.out.println("Method around after " + arg0.getMethod().getName()); return null; }配置通知:
<span style="white-space:pre"> </span><bean id="withAopAdvice" class="ray.interceptor.MethodAroundInterceptor"/>2、定义一个切入点:
<bean id="withAopPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*withAop" /> </bean>
3、定义一个切面:(这里用DefaultPointcutAdvisor)
<bean id="withAopAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="withAopAdvice" /> <property name="pointcut" ref="withAopPointcut" /> </bean>
最后要在代理中配置
<bean id="aopServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces" value="ray.aop.IAopService" /> <!-- 制定需要代理的对象(接口实现类) --> <property name="target"> <ref bean="aopService" /> </property> <!-- before - arround before - method - arround after - after --> <property name="interceptorNames"><!-- 定义通知 --> <list> <value>withAopAdvisor</value> </list> </property> </bean>
4、测试下:
private static void TestInterceptor() { //通过代理类获得bean实例,其实是在代理类中方法执行前后加入代码 IAopService service = (IAopService)factory.getBean("aopServiceProxy"); //如果用构造函数或者工厂方法获得bean实例,不能实现AOP // IAopService service = (IAopService) factory.getBean("aopService"); service.withAop(); service.withOutAop(); }看下输出:
Method around before withAop run withAop method--------- Method around after withAop run withOutAop method---------另外:Spring给我们封装了几个常用的切面:
例如: NameMatchMethodPointcutAdvisor
上面的配置就可以这样配置了:
<!-- 要是拦截器在某个方法后执行,需要安装到NameMathched。。Advisor中 --> <bean id="aopMethodThrowsExceptionInterceptor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="advice"> <bean class="ray.interceptor.MethodThrowExceptionInterceptor"></bean> </property> <property name="mappedName" value=".*withAop"></property> </bean>
只是把切入点的配置换成了mappedName而已,因为里面封装了mappedName为切入点:
相关文章推荐
- Java多线程干货系列—(一)Java多线程基础
- 搭建CTS测试环境
- 【Leetcode】:344. Reverse String 问题 in JAVA
- Eclipse中使用SVN
- eclipse 和 android studio 快捷键对比
- Spring IOC学习计划
- 3分钟教会你如何看eclipse中的崩溃信息
- Eclipse下svn的创建分支/合并/切换使用
- java反射中getDeclaredField和getField的区别
- 类型转换错误java.math.BigDecimal cannot be cast to java.lang.String
- 使用Handler容易产生的内存泄露以及介绍下Java的4种引用
- 使用Handler容易产生的内存泄露以及介绍下Java的4种引用
- Java开发经验
- ubuntu下访问串口
- JavaWeb过滤器.监听器.拦截器-原理&区别-个人总结
- Java中的迭代器Iterator与迭代器模式
- spring 整合CXF框架抛异常
- spring boot test
- 一个经典例子让你彻彻底底理解java回调机制
- spring基本配置,并自动注入