spring 切入点 后置通知
来源:互联网 发布:传智播客java教程下载 编辑:程序博客网 时间:2024/04/29 13:11
Spring的AOP其实使用的是一种代理机制,可以算是代理或是装饰模式的应用。下面是一些常用的术语:
Aspect:通常翻译成切面,是一个横跨多个核心逻辑的功能,比如说散落在系统中多个角落的一块代码。
Joinpoint:通常翻译成连接点,是说程序中什么地方插入一个Aspect。
Pointcut:切入点,一组Joinpoint的集合,比如一个Aspect需要在每个以query开头的方法时执行,可以用正则(.*query.*)来表示这一组Joinpoint。
Advice:对Joinpoint的增强。
另外还有Introduct,Weaving,Interceptor,Target Object,Proxy。
常用的Advice:
1.MethodBeforeAdvice
2.AfterReturningAdvice
3.ThrowsAdvice
4.MethodInterceptor
1. 如果对UserServiceImpl增加advice增强,例如:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 配置UserServiceImpl -->
<bean id="userServiceTarget" class="example.chapter4.UserServiceImpl">
<property name="userDao">
<bean class="example.chapter4.UserDao" />
</property>
</bean>
<!-- 定义MethodBeforeAdvice -->
<bean id="loginMethodBeforeAdvice" class="example.chapter4.LoginMethodBeforeAdvice" />
<!-- 定义AfterReturningAdvice -->
<bean id="loginAfterReturningAdvice" class="example.chapter4.LoginAfterReturningAdvice" />
<!-- 定义ThrowsAdvice -->
<bean id="loginThrowsAdvice" class="example.chapter4.LoginThrowsAdvice" />
<!-- 定义MethodInterceptor -->
<bean id="loginAroundAdvice" class="example.chapter4.LoginAroundAdvice" />
<!-- 配置AOP -->
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>loginMethodBeforeAdvice</value>
<value>loginAfterReturningAdvice</value>
<value>loginThrowsAdvice</value>
</list>
</property>
<property name="target" ref="userServiceTarget" />
</bean>
</beans>
2.但是,有个缺点,这样使用的话,会对UserServiceImpl中每个方法都加上这几种advice,这个时候就需要Advisor。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 配置UserServiceImpl -->
<bean id="userServiceTarget" class="example.chapter4.UserServiceImpl">
<property name="userDao">
<bean class="example.chapter4.UserDao" />
</property>
</bean>
<!-- 使用NameMatchMethodPointcutAdvisor来定义loginBeforeAdvisor -->
<bean id="loginBeforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 指定切入方法为login -->
<property name="mappedName" value="login" />
<!-- 指定Advice -->
<property name="advice">
<bean class="example.chapter4.LoginMethodBeforeAdvice" />
</property>
</bean>
<!-- 使用RegexpMethodPointcutAdvisor来定义createAfterAdvisor -->
<bean id="createAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 指定切入方法为.*create.*,拦截所有以create开头的方法 -->
<property name="pattern" value=".*create.*" />
<!-- 指定Advice -->
<property name="advice">
<bean class="example.chapter4.CreateAfterReturningAdvice" />
</property>
</bean>
<!-- 配置AOP -->
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>loginBeforeAdvisor</value>
<value>createAfterAdvisor</value>
</list>
</property>
<property name="target" ref="userServiceTarget" />
</bean>
</beans>
这样一来,可以分别对不同的方法进行分别增强。
3.不过,还是有个问题,用户此时可以绕过AOP代理直接获取原始bean,那么,就需要自动代理来弥补这个问题。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 配置UserServiceImpl -->
<bean id="userService" class="example.chapter4.UserServiceImpl">
<property name="userDao">
<bean class="example.chapter4.UserDao" />
</property>
</bean>
<bean id="loginBeforeAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 限定切入点仅作用于UserService的login()方法 -->
<property name="pattern" value=".*UserService/.login" />
<property name="advice">
<bean class="example.chapter4.LoginMethodBeforeAdvice" />
</property>
</bean>
<bean id="createAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!-- 限定切入点仅作用于UserService的create()方法 -->
<property name="pattern" value=".*UserService/.create" />
<property name="advice">
<bean class="example.chapter4.CreateAfterReturningAdvice" />
</property>
</bean>
<!-- 配置BeanNameAutoProxyCreator -->
<!--
<bean id="beanNameAutoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="userService" />
<property name="interceptorNames">
<list>
<value>loginBeforeAdvisor</value>
<value>createAfterAdvisor</value>
</list>
</property>
</bean>
-->
<!-- 配置DefaultAdvisorAutoProxyCreator -->
<bean id="defaultAutoProxy"
class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>
经过这样配置后,可以将advisor应用的某个接口的某些方法上。
BeanNameAutoProxyCreator 与DefaultAdvisorAutoProxyCreator的不同,是后者可以自动查找advisor(不查找advice)和普通bean,然后根据advisor计算他们能够适用于哪些bean,凡是能被适用的bean都将被自动创建AOP代理。
对于.*UserService/.create的形式,如果不指定接口,spring会去找其他符合条件的类中的create方法,那么会提示CGLIB没有找到。因为AOP代理对接口适用JDK动态代理,而对类级别使用CGLIB代理。
4.还有一中Introduction的使用,它是一种拦截器,我感觉是装饰模式的一种应用
比如说有一个类User,在编译器类A并未静态实现其他接口,而想动态增强其行为,可以创建一个接口Mutable
配置代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<!-- 具有Mutable接口的代理Bean -->
<bean id="user" scope="prototype"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="target" />
<property name="proxyTargetClass" value="true" />
<property name="proxyInterfaces">
<list>
<value>example.chapter4.Mutable</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>introductionAdvisor</value>
</list>
</property>
</bean>
<bean id="introductionAdvisor" scope="prototype"
class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg>
<bean class="example.chapter4.MutableInterceptor" />
</constructor-arg>
</bean>
<!-- 原始Bean -->
<bean id="target" class="example.chapter4.User" scope="prototype">
<property name="username" value="default-name" />
<property name="password" value="PaSsWoRd" />
<property name="email" value="default-email@abc.xyz" />
</bean>
</beans>
- spring 切入点 后置通知
- Spring AOP-后置通知
- Spring--AOP-后置通知
- Spring AOP-通知-后置通知
- spring之AOP---后置通知
- spring中前置通知与后置通知
- Spring AOP前置通知和后置通知
- Spring前置通知与后置通知
- Spring 基于注解,实现 前置通知、后置通知、返回通知、 异常通知 、后置通知
- Spring aop 前置通知、后置通知、返回通知、 异常通知 、后置通知
- spring的前置通知,后置通知,环绕通知
- spring学习笔记十三 前、后置通知
- Spring AOP 后置通知修改响应httpstatus
- Spring学习笔记之前置通知&后置通知
- spring的AOP基础、前置通知与后置通知
- Spring中的异常通知与后置通知怎么回事啊?
- Spring AOP中的前置通知和后置通知详解
- Spring学习笔记之前置通知、后置通知
- [回忆]2007年的GDNT研发广东北电辞职信.
- SQL触发器语法参考
- 两个日期之间的天数
- 使用link方法安装eclipse插件(svn)
- oracle JOB迁移办法
- spring 切入点 后置通知
- 字符编码格式
- 一些JS操作在IE/FireFox/google浏览器间的兼容问题
- 图形识别与理解 - 研究生终于混毕业了
- 实战tips of svn installation
- JSONObject类方法使用
- extjs中xtype类型
- c/c++面试总结
- 搜盒,一个搜索和收藏工具,希望您喜欢