白话Spring(基础篇)---AOP(实例篇-2)
2016-03-05 10:20
471 查看
[一知半解,就是给自己挖坑]
在AOP(实例篇-1)中,我们演示了针对某个类对象的全部方法进行AOP切面处理,接下来,我们来演示一下,如何在一个类对象中,只针对某个方法进行AOP切面处理。
准备工作:
a.操作系统:win7 x64
b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12
c.工程仍然是上一个Spring091。
-------------------------------------------------------------------------------------------------------------------------------------
1.创建Pointcut.java文件,具体内容如下:
a.首先,我们先定义了需要我们加入AOP的对象,设置id为baseBusiness。
b.接着,定义了4个不同类型的通知,通知分别继承于AOP接口,具体内容请查看前文详情
c.然后,我们分别定义了通知类型的作用范围,注意观察每一种通知范围的配置方式。
d.最后,设置ProxyFactoryBean。具体解释请查看代码中的注释部分
3.修改IBaseBusiness.java文件,具体内容如下:
4.修改BaseBusiness.java,具体内容如下:
5.测试方法:运行main方法,分别执行接口中提供的三种方法,观察控制台输出即可。
-------------------------------------------------------------------------------------------------------------------------------------
备注:
1.后置通知中拦截规则:
后置通知中的bean下的patterns属性下添加一些正则表达式规则,能够匹配这些规则的方法就会被拦截。值得一提的是,这儿匹配的是方法的完整路径,包括类名已经类的包名。回顾一下,这儿的目标类是com.java.ingo.service.impl,它里面只有三个方法add,delete,modify。这三个方法的完整路径就是com.java.ingo.service.impl.BaseBusiness.add
和 com.java.ingo.service.impl.BaseBusiness.add .delete等 。这儿写的正则表达式是.*delete,明显它可以匹配com.java.ingo.service.impl.BaseBusiness.add .delete,所以这个方法会被拦截。假设将正则表达式写成delete,那么它不能匹配com.java.ingo.service.impl.BaseBusiness.add .delete 这整个字符串,所以讲不会起作用。如果要拦截方法名中包含abc的方面,正则表达式写成.*abc.*就可以了(当然包名和类名不能是abc)
2.环绕通知通的拦截规则:
环绕通知中可以用*通配符,如,*User就代表所有以User结尾的方法。注意这儿只匹配方法名,不会管类名和包名了。
-------------------------------------------------------------------------------------------------------------------------------------
至此,白话Spring(基础篇)---AOP(实例篇-2)结束。
参考资料:
Spring官网:http://spring.io/docs
其他博文: http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example http://tonl.iteye.com/blog/1966075
在AOP(实例篇-1)中,我们演示了针对某个类对象的全部方法进行AOP切面处理,接下来,我们来演示一下,如何在一个类对象中,只针对某个方法进行AOP切面处理。
准备工作:
a.操作系统:win7 x64
b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12
c.工程仍然是上一个Spring091。
-------------------------------------------------------------------------------------------------------------------------------------
1.创建Pointcut.java文件,具体内容如下:
package com.java.ingo.point; import java.lang.reflect.Method; import org.springframework.aop.support.NameMatchMethodPointcut; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日上午11:43:23 *类说明 */ public class Pointcut extends NameMatchMethodPointcut { private static final long serialVersionUID = 3990456017285944475L; @SuppressWarnings("rawtypes") public boolean matches(Method method, Class targetClass) { // 设置单个方法匹配 this.setMappedName("delete"); // 设置多个方法匹配 String[] methods = { "delete","modify" }; //也可以用“ * ” 来做匹配符号 // this.setMappedName("get*"); this.setMappedNames(methods); return super.matches(method, targetClass); } }2.修改beans.xml文件,具体内容如下:
<?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:p="http://www.springframework.org/schema/p" 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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" default-autowire="byName"> <!-- ==============================利用spring自己的aop配置================================ --> <!-- 声明一个业务类 --> <bean id="baseBusiness" class="com.java.ingo.service.impl.BaseBusiness" /> <!-- 声明通知类 --> <bean id="baseBefore" class="com.java.ingo.advice.BaseBeforeAdvice" /> <bean id="baseAfterReturn" class="com.java.ingo.advice.BaseAfterReturnAdvice" /> <bean id="baseAfterThrows" class="com.java.ingo.advice.BaseAfterThrowsAdvice" /> <bean id="baseAround" class="com.java.ingo.advice.BaseAroundAdvice" /> <!-- 指定切点匹配类 --> <bean id="pointcut" class="com.java.ingo.point.Pointcut" /> <!-- 前置通知--> <bean id="matchBeforeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut"> <ref bean="pointcut" /> </property> <property name="advice"> <ref bean="baseBefore" /> </property> </bean> <!-- 后置通知--> <bean id="matchAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="patterns"> <list> <value>.*delete</value> </list> </property> <property name="advice"> <ref bean="baseAfterReturn" /> </property> </bean> <!-- 环绕通知--> <bean id="matchAroundAdvisor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"> <property name="mappedNames"> <list> <value>delete</value> </list> </property> <property name="advice"> <ref bean="baseAround" /> </property> </bean> <!-- 使用ProxyFactoryBean 产生代理对象 --> <bean id="businessProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 代理对象所实现的接口 ,如果有接口可以这样设置 --> <property name="proxyInterfaces"> <value>com.java.ingo.service.IBaseBusiness</value> </property> <!-- 设置目标对象 --> <property name="target"> <ref local="baseBusiness" /> </property> <!-- 代理对象所使用的拦截器 --> <property name="interceptorNames"> <list> <value>matchBeforeAdvisor</value> <value>matchAfterAdvisor</value> <value>matchAroundAdvisor</value> </list> </property> </bean> </beans>我们来看看配置文件中各个配置项的含义:
a.首先,我们先定义了需要我们加入AOP的对象,设置id为baseBusiness。
b.接着,定义了4个不同类型的通知,通知分别继承于AOP接口,具体内容请查看前文详情
c.然后,我们分别定义了通知类型的作用范围,注意观察每一种通知范围的配置方式。
d.最后,设置ProxyFactoryBean。具体解释请查看代码中的注释部分
3.修改IBaseBusiness.java文件,具体内容如下:
package com.java.ingo.service; import com.java.ingo.entity.Customer; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月5日上午10:40:25 *类说明 */ public interface IBaseBusiness { public void delete(Customer obj); public String add(String obj); public void modify(Customer customer); }
4.修改BaseBusiness.java,具体内容如下:
public class BaseBusiness implements IBaseBusiness { /** * 切入点 */ public void delete(Customer obj) { System.out.println("||///////////////////||"); System.out.println("删除用户:"+obj.getName()); System.out.println("||///////////////////||"); } public String add(String add) { System.out.println("||///////////////////||"); System.out.println("add用户:"+add); System.out.println("||///////////////////||"); return add; } public void modify(Customer obj) { System.out.println("|///////////////////||"); System.out.println("modify用户:"+obj.getName()); System.out.println("|///////////////////||"); } }
5.测试方法:运行main方法,分别执行接口中提供的三种方法,观察控制台输出即可。
-------------------------------------------------------------------------------------------------------------------------------------
备注:
1.后置通知中拦截规则:
后置通知中的bean下的patterns属性下添加一些正则表达式规则,能够匹配这些规则的方法就会被拦截。值得一提的是,这儿匹配的是方法的完整路径,包括类名已经类的包名。回顾一下,这儿的目标类是com.java.ingo.service.impl,它里面只有三个方法add,delete,modify。这三个方法的完整路径就是com.java.ingo.service.impl.BaseBusiness.add
和 com.java.ingo.service.impl.BaseBusiness.add .delete等 。这儿写的正则表达式是.*delete,明显它可以匹配com.java.ingo.service.impl.BaseBusiness.add .delete,所以这个方法会被拦截。假设将正则表达式写成delete,那么它不能匹配com.java.ingo.service.impl.BaseBusiness.add .delete 这整个字符串,所以讲不会起作用。如果要拦截方法名中包含abc的方面,正则表达式写成.*abc.*就可以了(当然包名和类名不能是abc)
2.环绕通知通的拦截规则:
环绕通知中可以用*通配符,如,*User就代表所有以User结尾的方法。注意这儿只匹配方法名,不会管类名和包名了。
-------------------------------------------------------------------------------------------------------------------------------------
至此,白话Spring(基础篇)---AOP(实例篇-2)结束。
参考资料:
Spring官网:http://spring.io/docs
其他博文: http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example http://tonl.iteye.com/blog/1966075
相关文章推荐
- 在网上看到的,加上自己学习到的,实践的,java中的内存优化问题
- JAVA启动参数整理
- 不依赖第三方jar包的通过java sax解析本地xml文件的实例代码
- Eclipse 学习笔记
- java中各种集合的用法和比较
- Java多线程顺序执行以及ThreadLocal
- JAVA訪问URL
- Java File类总结
- java写一十进制转十六进制代码思路
- java覆盖equals()方法时总要覆盖hashCode()
- eclipse使用外部工具快捷编译jni
- 在Eclipse的android工程下创建多个java文件
- Java IO
- JAVA集合2
- [Java并发包学习七]解密ThreadLocal
- Spring进阶之路(5)-Spring创建Bean的三种方式
- Spring进阶之路(4)-容器中Bean作用域与集合类型配置
- Spring进阶之路(3)-bean获得Spring的容器
- 无限极java设计与实现整理
- Usage: AddDimensionedImage imageFile outputFile eclipse 运行程序出错