面向切面编程(二)
来源:互联网 发布:软件加license 编辑:程序博客网 时间:2024/05/16 16:00
Pointcut 即切入点,用于配置切面的切入位置。由于spring中切入点的粒度是方法级的,因此spring AOP中Pointcut的作用是配置哪些类中哪些方法在用户定义的切入点之内、哪些方法应该被过滤排除。spring的Pointcut分为静态Pointcut、动态Pointcut、和用户自定义的Pointcut。其中静态Pointcut只需考虑类名、方法名;动态Pointcut除此之外还要考虑方法的参数,以便在运行时可以动态的确定切入点的位置。
一、静态Pointcut
通知实现类:
package com.mfc.advice;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;/** * 2017年7月11日00:07:01 * 一个普通的前置通知 * */public class PeopleBeforeAdvice implements MethodBeforeAdvice {public void before(Method method, Object[] objects, Object object) throws Throwable {System.out.println(object.getClass().getSimpleName()+" is "+method.getName()+"!");}}
切面实现类:
package com.mfc.advisor;import java.lang.reflect.Method;import org.springframework.aop.ClassFilter;import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;import com.mfc.models.People;/** * 2017年7月11日00:09:53 * 定义一个切面,过滤那些不需要使用前置通知的方法 * */public class PeopleAdvisor extends StaticMethodMatcherPointcutAdvisor {public boolean matches(Method method, Class<?> class1) {//切点方法匹配规则,方法名为speakingreturn "speaking".equals(method.getName());}//切点类匹配规则,为People类或其子类public ClassFilter getClassFilter(){return new ClassFilter() {public boolean matches(Class<?> arg0) {return People.class.isAssignableFrom(arg0);}};}}
模拟业务类:
public class People {//讲话public void speaking() {System.out.println("嗨,大家好!");}//跑步public void running(){System.out.println("正在跑...");}//吃饭public void eating(){System.out.println("正在吃...");}//死亡public void died(){System.out.println("忧郁而死...");}}
测试类:
package com.mfc.models;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");People people=(People) applicationContext.getBean("proxyFactoryBean");people.speaking();people.running();people.eating();people.died();}}
配置文件:
<bean id="peopleTarget" class="com.mfc.models.People"></bean><bean id="peopleAdvice" class="com.mfc.advice.PeopleBeforeAdvice"></bean><!-- 定义切面 --><bean id="peopleAdvisor" class="com.mfc.advisor.PeopleAdvisor"><!-- 注入前置通知 --><property name="advice" ref="peopleAdvice"></property></bean><bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="interceptorNames"><idref bean="peopleAdvisor"/></property><property name="target" ref="peopleTarget"></property></bean>
二、使用正则表达式的静态Ponintcut
使用正则表达式后就不需要以上的切面实现类了,可以直接在配置文件中配置:
<bean id="peopleTarget" class="com.mfc.models.People"></bean><bean id="peopleAdvice" class="com.mfc.advice.PeopleBeforeAdvice"></bean><!-- 定义切面 --><bean id="peopleAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><property name="patterns"><list><value>.*ing</value> <!-- 以ing结尾的方法 --></list></property><!-- 注入前置通知 --><property name="advice" ref="peopleAdvice"></property></bean><bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="interceptorNames"><idref bean="peopleAdvisor"/></property><property name="target" ref="peopleTarget"></property></bean>
三、动态Pointcut
由于动态切入点除了要考虑方法的名称等静态信息外,还要考虑方法的参数。由于它是动态的,在执行时既要计算方法的静态信息,还要计算其参数,结果也不能被缓存,因此动态切入点要消耗更多的系统资源。
实例:
通知实现类:
public class PeopleBeforeAdvice implements MethodBeforeAdvice {public void before(Method method, Object[] objects, Object object) throws Throwable {System.out.println(object.getClass().getSimpleName()+" is "+method.getName()+"!");}}切面实现类:
package com.mfc.advisor;import java.lang.reflect.Method;import org.springframework.aop.ClassFilter;import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;import com.mfc.models.People;/** * 2017年7月11日00:09:53 * 定义一个切面,过滤那些不需要使用前置通知的方法 * */public class PeopleAdvisor extends StaticMethodMatcherPointcutAdvisor {public boolean matches(Method method, Class<?> class1) {//切点方法匹配规则,方法名为speakingreturn "speaking".equals(method.getName());}//切点类匹配规则,为People类或其子类public ClassFilter getClassFilter(){return new ClassFilter() {public boolean matches(Class<?> arg0) {return People.class.isAssignableFrom(arg0);}};}}
模拟dao层:
package com.mfc.models;public class People {//讲话public void speaking() {System.out.println("嗨,大家好!");}//跑步public void running(){System.out.println("正在跑...");}//吃饭public void eating(){System.out.println("正在吃...");}//死亡public void died(){System.out.println("忧郁而死...");}}
模拟service业务层;
package com.mfc.models;public class PeopleDelegate {private People people;public void setPeople(People people){this.people=people;}public void living(){people.eating();people.died();}}测试方法:
package com.mfc.models;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");People people=(People) applicationContext.getBean("people");people.speaking();people.running();people.eating();people.died();PeopleDelegate delegate=new PeopleDelegate();delegate.setPeople(people);delegate.living();}}
spring配置文件:
<bean id="peopleTarget" class="com.mfc.models.People"></bean><bean id="peopleAdvice" class="com.mfc.advice.PeopleBeforeAdvice"></bean><!-- 定义切面 --><bean id="peopleDelegate" class="org.springframework.aop.support.ControlFlowPointcut"><!-- 指定第一个参数为 PeopleDelegate类 --><constructor-arg type="java.lang.Class" value="com.mfc.models.PeopleDelegate"></constructor-arg><!-- 指定第二个参数为living的方法 --><constructor-arg type="java.lang.String" value="living"></constructor-arg></bean><bean id="peopleAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"><property name="pointcut" ref="peopleDelegate"></property><!--指定切点 --><property name="advice" ref="peopleAdvice"></property><!--指定通知 --></bean><bean id="people" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="interceptorNames"><idref bean="peopleAdvisor"/></property><property name="target" ref="peopleTarget"></property></bean>
四、自动代理
1、使用BeanNameAutoproxyCreator
前置通知实现类:
public class CheckUser implements MethodBeforeAdvice {public void before(Method method, Object[] objects, Object object) throws Throwable {String username = (String) objects[0]; System.out.println("正在对【"+username+"】用户进行身份检测...");}}模拟用户登录接口:
public interface UserLogin {public void login(String username);}实现用户登录接口:
public class UserLoginImpl implements UserLogin {public void login(String username) {System.out.println(username+"正在登陆系统后台...");}}测试类:
public class BeforeAdviceTest { public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");UserLogin login=(UserLogin) applicationContext.getBean("userlogin");login.login("孟凡诚");}}spring配置文件:
<!-- 前置通知 --><bean id="checkUser" class="com.mfc.advice.CheckUser"></bean><!-- 被代理的bean --><bean id="userlogin" class="com.mfc.impl.UserLoginImpl"></bean><!-- 自动代理 --><bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"><!-- 指定被代理的bean --><property name="beanNames" value="userlogin"></property><!-- 指定通知 --><property name="interceptorNames"><idref bean="checkUser"/></property></bean>
2、使用DefaultAdvisorAutoProxyCreator
前置通知实现类:
public class PeopleBeforeAdvice implements MethodBeforeAdvice {public void before(Method method, Object[] objects, Object object) throws Throwable {System.out.println(object.getClass().getSimpleName()+" is "+method.getName()+"!");}}切面实现类:
package com.mfc.advisor;import java.lang.reflect.Method;import org.springframework.aop.ClassFilter;import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;import com.mfc.models.People;/** * 2017年7月11日00:09:53 * 定义一个切面,过滤那些不需要使用前置通知的方法 * */public class PeopleAdvisor extends StaticMethodMatcherPointcutAdvisor {public boolean matches(Method method, Class<?> class1) {//切点方法匹配规则,方法名为speakingreturn "speaking".equals(method.getName());}//切点类匹配规则,为People类或其子类public ClassFilter getClassFilter(){return new ClassFilter() {public boolean matches(Class<?> arg0) {return People.class.isAssignableFrom(arg0);}};}}模拟dao层:
package com.mfc.models;public class People {//讲话public void speaking() {System.out.println("嗨,大家好!");}//跑步public void running(){System.out.println("正在跑...");}//吃饭public void eating(){System.out.println("正在吃...");}//死亡public void died(){System.out.println("忧郁而死...");}}测试类:
public class Test {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");People people=(People) applicationContext.getBean("people");people.speaking();people.running();people.eating();people.died();}}配置文件:
<bean id="people" class="com.mfc.models.People"></bean><bean id="peopleAdvice" class="com.mfc.advice.PeopleBeforeAdvice"></bean><!-- 配置自动代码创建器 --><bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean><bean id="peopleAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"><!-- 使用正则表达式 --><property name="patterns"><value>.*ing</value><!-- 以ing结尾的方法 --></property><!-- 注入前置通知 --><property name="advice" ref="peopleAdvice"></property></bean>
springaop示例源码下载:http://download.csdn.net/detail/fancheng614/9894591
阅读全文
0 0
- 面向切面编程(二)
- 面向切面编程二
- Spring面向切面编程二
- AOP面向切面编程(二) 动态代理
- spring学习(二)AOP面向切面编程
- Spring框架(二)--AOP面向切面编程
- 面向切面编程AOP的浅显理解(二)
- Spring配置过程 (二)面向切面编程AOP
- 达内云笔记(二) AOP面向切面编程
- 面向切面编程(转载)
- Aop(面向切面编程)
- 面向切面编程(AOP)
- AOP(面向切面编程)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(AOP)
- 面向切面编程(一)
- JAVA Set 交集,差集,并集
- jstl标签在jsp页面对字符串的操作
- JAVA基础1
- 算法题目---二叉树的镜像
- Android常用控件TextView的属性详解
- 面向切面编程(二)
- Git使用总结
- js使用map过滤数组中对象
- 端口分类调研
- apk加载32bit 64bit
- Sqoop-1.4.6的简要安装
- 详解Java中的clone方法
- 你真的知道敏捷和迭代吗?
- POJ