Spring入门(AOP API、ProxyFactoryBean其一)
来源:互联网 发布:八千湘女嫁新疆知乎 编辑:程序博客网 时间:2024/05/19 00:07
介绍
这是Spring1.2历史用法,现在(V4.0)仍然支持
这是SpringAOP基础,不得不了解
现在的用法也是基于历史的,只是更简便了
Pointcut
Pointcut作为一个接口,它有几个实现类,这里以其中一个来介绍,他就是NameMatchMethodPointcut。它根据方法名字进行匹配。
它有一个成员变量mappedNames,匹配的方法名集合。
来看一下下面这个配置文件的例子:
<bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut"> <property name="mappedNames"> <list> <value>sa*</value> </list> </property></bean>
定义一个bean,class就是刚才提到的。property是里边的属性,里边用一个list,list表示当前这个属性是一个集合,list里边就是value,这里写了一个,也可以写多个,这里的意思是sa开头的所有方法。
然后看一个例子。
首先是配置文件:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <bean id="bizLogicImplTarget" class="com.imooc.aop.api.BizLogicImpl"></bean> <bean id="pointcutBean" class="org.springframework.aop.support.NameMatchMethodPointcut"> <property name="mappedNames"> <list> <value>sa*</value> </list> </property> </bean></beans>
这里看到有一个bean,class为BizLogicImpl。另一个bean是定义好了一个切入点。
首先我们有一个BizLogic接口:
public interface BizLogic { String save();}
然后是它的一个实现类
public class BizLogicImpl implements BizLogic { public String save() { System.out.println("BizLogicImpl : BizLogicImpl save."); return "BizLogicImpl save.";// throw new RuntimeException(); }}
xml文件中配置了这个bean,并且id是bizLogicImplTarget,至于为什么是Target,后边的例子里会有说明。
Before Advice
一个简单的通知类型
只是在进入方法之前被调用,不需要MethodInvocation对象(和基于配置中讲到的是差不多的)
前置通知可以在连接点执行之前插入自定义行为,但不能改变返回值
接着刚才的例子,我们新建一个类MoocBeforeAdvice类实现MethodBeforeAdvice接口,里边输出内容即自定义行为:
public class MoocBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("MoocBeforeAdvice : " + method.getName() + " " + target.getClass().getName()); }}
这样一个前置通知就定义好了。暂时不去单元测试类执行它,因为执行它需要用到后边讲到的内容。
Throw advice
如果连接点抛出异常,throws advice在连接点返回后被调用
如果throws-advice的方法抛出异常,那么它将覆盖原有异常
接口org.springframework.aop.ThrowsAdvice不包含任何方法,仅仅是一个声明,实现类需要实现类似下面的方法:
void afterThrowing([Method,args,target],ThrowableSubclass);
我们来看一下它的说明
这是几种形式,有一个特点就是异常是必须有的,前边的内容可有可无。然后图中代码的例子就是这样。
继续刚才的例子,在代码中定义一个类MoocThrowsAdvice实现接口ThrowsAdvice
public class MoocThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Exception ex) throws Throwable { System.out.println("MoocThrowsAdvice afterThrowing 1"); } public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable { System.out.println("MoocThrowsAdvice afterThrowing 2 : " + method.getName() + " " + target.getClass().getName()); }}
只是完成了定义,具体使用依赖后边的内容。
After Returning advice
后置通知必须实现org.springframework.aop.AfterReturningAdvice接口
可以访问返回值(但不能进行修改)、被调用的方法、方法的参数和目标
如果抛出异常,将会抛出拦截器链,替代返回值
继续刚才的例子,我们自己定义一个类MoocAfterReturningAdvice继承AfterReturningAdvice接口:
public class MoocAfterReturningAdvice implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("MoocAfterReturningAdvice : " + method.getName() + " " + target.getClass().getName() + " " + returnValue); }}
Interception around advice
Spring的切入点模型使得切入点可以独立与advice重用,以针对不同的advice可以使用相同的切入点。这个和之前基于xml配置文件的AOP实现方式类似,切入点可以在外面单独配置,每一个advice都可以使用相同的切入点。
定义一个类MoocMethodInterceptor继承MethodInterceptor接口:
public class MoocMethodInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("MoocMethodInterceptor 1 : " + invocation.getMethod().getName() + " " + invocation.getStaticPart().getClass().getName()); Object obj = invocation.proceed(); System.out.println("MoocMethodInterceptor 2 : " + obj); return obj; }}
返回的是invocation的proceed方法的返回值。在方法执勤啊和之后都进行输出,我们可以通过invication可以得到method,进一步得到方法的名称。
Introduct advice
和在xml配置中实现的Introduction advice中实现的是一样的
Spring把引入通知作为一种特殊的拦截通知
需要IntroductionAdvisor和IntroductionInterceptor两个接口
仅适用于类,不能和任何切入点一起使用
然后来看一下这两个接口的内容:
IntroductionInterceptor里边有一个implementsInterface,就像我们在前边的配置中配置的那样,使它实现了哪个接口。还有IntroductionAdvisor里的内容。这些都对应了我们基于xml配置的SpringAOP实现里的一些内容。
然后看一下一个Introduction advice的小例子。这个例子实在Spring test suit里边提供的一个例子。用法:
如果调用lock()方法,希望所有的setter方法抛出LockedException异常(如使物体不可变,这是AOP典型例子)
需要一个完成繁重任务的IntroductionInterceptor,这种情况下,可以使用org.springframework.aop.support.DelegatingIntroductionInterceptor,而不是去实现这个接口
public interface Lockable{ void lock(); void unlock(); boolean locked();}
来看一下代码
接口
public interface Lockable { void lock(); void unlock(); boolean locked();}
实现类
public class LockMixin extends DelegatingIntroductionInterceptor implements Lockable { private static final long serialVersionUID = 6943163819932660450L; private boolean locked; public void lock() { this.locked = true; } public void unlock() { this.locked = false; } public boolean locked() { return this.locked; } public Object invoke(MethodInvocation invocation) throws Throwable { if (locked() && invocation.getMethod().getName().indexOf("set") == 0) { throw new RuntimeException(); } return super.invoke(invocation); }}
invoke方法里的意思是,如果当前是被锁住,并且方法的名称中包含set,那么不希望执行set方法去改变物体的属性。如果符合这样的内容就抛出一个异常,否则正常执行。
里边做了一点修改,返回的是RuntimeException,而不是LockedException
introduction advisor比较简单,持有独立的LockMixin实例:
public class LockMixinAdvisor extends DefaultIntroductionAdvisor { private static final long serialVersionUID = -171332350782163120L; public LockMixinAdvisor() { super(new LockMixin(), Lockable.class); }}
这里实现的是spring提供的用来简化操作的DefaultIntroductionAdvisor 类。
Advisor API in Spring
Advisor是仅包含一个切入点表达式关联的单个通知的方面
除了introductions,advisors可以用于任何通知
org.springframework,aop.support.DefaultPointcutAdvisor是最常用的advisor类,它可以与MethodInterceptor,BeforeAdvice或者ThrowsAdvice一起使用
它可以混合在Spring同一个AOP代理的advisor和advice
- Spring入门(AOP API、ProxyFactoryBean其一)
- Spring入门(AOP API、ProxyFactoryBean其二)
- Spring入门(AOP API,ProxyFactoryBean其三)
- Spring入门(Schema-based AOP其一)
- Spring AOP小测试(ProxyFactoryBean)
- Spring AOP-编程的方式创建代理类(ProxyFactoryBean)
- 浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- Spring Aop(十三)——ProxyFactoryBean创建代理对象
- Spring AOP实现机制(二)--ProxyFactoryBean---将Spring AOP和Spring IoC容器相结合
- Spring AOP之基于ProxyFactoryBean的代理
- Spring -- org.springframework.aop.framework.ProxyFactoryBean
- Spring AOP之ProxyFactoryBean与BeanNameAutoProxyCreator
- Spring学习笔记 —— AOP(面向切面编程) 之使用ProxyFactoryBean实现AOP
- 做一个合格的程序猿之浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- 用ProxyFactoryBean创建AOP代理(转)
- spring aop(五)--ProxyFactoryBean创建代理的实现
- spring 直接使用ProxyFactoryBean 实现AOP 流程小结
- Spring源码分析-初识ProxyFactoryBean(五)
- Sublime Text 3143注册码
- leetcode 001 Two Sum
- [随笔一写]--在本科的第一个月
- javascript_01
- 串口通讯介绍(有见地,学法可取)
- Spring入门(AOP API、ProxyFactoryBean其一)
- eclipse使用教程(图文)
- Detachment
- Ajax动态拼接HTML,JS失效的解决——Jquery的事件委托
- Shell函数返回探究
- Android:Android应用和开发环境
- maven项目update后jdk版本变为1.5
- python爬取m3u8连接的视频
- Python中通过requests模块发送POST请求.