22_AOP_切面——静态切面
【Spring AOP 如何定位连接点】
1.增强提供了连接点的方位信息:如织入到方法前面、后面等。
2.切点描述的是织入到哪些类的哪些方法上。
【切点】
Spring通过org.springframework.aop.Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成,通过ClassFilter定位到某些特定的类,通过MethodMatcher定位到某些特定的方法。这样,Pointcut就拥有了描述某些类的某些特定方法的能力。
可以看到:
ClassFilter只定义了一个方法matches(Class clazz),其参数代表一个被检测的类,该方法判别被检测的类是否匹配过滤条件。
Spring提供了两种方法匹配器:静态方法匹配器和动态方法匹配器。
1.静态方法匹配器
仅对方法名签名(包括方法名和入参类型及顺序)进行匹配。静态匹配仅判断一次。
2.动态方法匹配器
会在运行期间检查方法入参的值。动态匹配因为每次调用方法的入参可能不一样,导致每次调用方法都必须判断,因此动态匹配对性能的影响较大。
一般情况,动态匹配不常使用。
方法匹配器的类型由MethodMatcher接口的isRuntime()方法决定,返回false表示是静态方法匹配器,返回true表示是动态方法匹配器。
【切点类型】
Spring提供了6种切点:
1.静态方法切点:org.springframework.aop.support.StaticMethodMatcherPointcut
StaticMethodMatcherPointcut是静态方法切点的抽象基类,默认情况下匹配所有的类。StaticMethodMatcherPointcut有两个重要的子类:NameMethodMatcherPointcut和AbstractRegexMethodPoint。前者提供简单的字符串匹配方法签名,后者使用正则表达式匹配方法签名。
2.动态方法切点:org.springframework.aop.support.DynamicMethodMatcherPointcut
DynamicMethodMatcherPointcut是动态方法切点的抽象基类,默认情况下它匹配所有的类。DynamicMethodMatcherPointcut已过时!!使用DefaultPointcutAdvisor和DynamicMethodPointcut动态方法匹配器代替。
3.注解切点
4.表达式切点
5.流程切点
6.复合切点
【切面类型】
Spring使用org.springframework.aop.Advisor接口表示切面的概念。
一个切面同时包含横切代码和连接点信息。切面分为三类:一般切面、切点切面、引介切面。
1.一般切面:Advisor
它仅包含一个Advice,Advice包含了横切代码和连接点的信息,所以Advice本身就是一个简单的切面,只不过它代表的是所有目标类的所有方法。由于这个横切面过于宽泛,所以一把不会直接使用。
2.切点切面:PointcutAdvisor
包含Advice和Pointcut两个类。我们可以通过类、方法名以及方法方位等信息灵活定义切面的连接点,提供更具适用性的切面。
3.引介切面:IntroductionAdvisor
引介切面是对应引介增强的特殊的切面,它应用于类层面之上,所以引介切点适用ClassFilter进行定义。
【静态普通方法名匹配切面 例子】
【奔驰车类:BenzCar.java】
package com.Higgin.part4; public class BenzCar {
public void driving(){
System.out.println("奔驰车在行驶...");
}
}
【宝马车类:BMWCar.java】
package com.Higgin.part4; public class BMWCar {
public void driving(){
System.out.println("宝马车在行驶...");
}
}
【汽车切面类:CarAdvisor.java】
package com.Higgin.part4; import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
/**
* 汽车类的切面CarAdvisor类
* 实现接口:StaticMethodMatcherPointcutAdvisor
* 实现StaticMethodMatcherPointcutAdvisor接口唯一需要定义的是matches()方法,
*
*/
public class CarAdvisor extends StaticMethodMatcherPointcutAdvisor{ /**
* 切点方法 匹配
* 匹配规则:方法名为driving
* 默认情况下,匹配所有的类
*/
@Override
public boolean matches(Method method, Class<?> clazz) {
return "driving".equals(method.getName());
} /**
* 通过覆盖getClassFilter()方法,让它仅匹配BenzCar类及其子类
*/
public ClassFilter getClassFilter(){
return new ClassFilter() {
/**
* 切点类 匹配
* 匹配规则:为BenzCar类或其子类
*/
@Override
public boolean matches(Class<?> clazz) {
return BenzCar.class.isAssignableFrom(clazz);
}
};
} }
【driving方法的前置增强类:DrivingBeforeAdvice.java】
package com.Higgin.part4; import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice; /**
* Driving的前置增强类
*/
public class DrivingBeforeAdvice implements MethodBeforeAdvice{ @Override
public void before(Method method, Object[] args, Object obj) throws Throwable {
System.out.println("要增强的是:"+obj.getClass()+"类 ---"+method.getName()+"方法"); //得到切点的信息
System.out.println("【前置增强】做好行驶前的准备工作...");
}
}
【Spring的xml配置文件:part4.xml】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 要增强的目标对象1 -->
<bean id="benzTarget" class="com.Higgin.part4.BenzCar"/>
<!-- 要增强的目标对象2 -->
<bean id="bmwTarget" class="com.Higgin.part4.BMWCar"/> <!-- 前置增强 -->
<bean id="drivingBeforeAdvice" class="com.Higgin.part4.DrivingBeforeAdvice" /> <!-- 切面 -->
<bean id="carAdvisor" class="com.Higgin.part4.CarAdvisor"
p:advice-ref="drivingBeforeAdvice"/> <!-- Spring代理工厂的成员变量配置 -->
<bean id="parent" abstract="true"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="carAdvisor"
p:proxyTargetClass="true"
/> <!-- Benz代理 -->
<bean id="benz" parent="parent" p:target-ref="benzTarget" />
<!-- BMW代理 -->
<bean id="bmw" parent="parent" p:target-ref="bmwTarget" />
</beans>
【测试类:TestCarAdvisor.java】
package com.Higgin.part4.Test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Higgin.part4.BMWCar;
import com.Higgin.part4.BenzCar; public class TestCarAdvisor {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("part4.xml"); BenzCar benz= (BenzCar) context.getBean("benz");
BMWCar bmw=(BMWCar) context.getBean("bmw"); benz.driving(); //奔驰车的driving方法
System.out.println("===========================");
bmw.driving(); //宝马车的driving方法
}
}
【运行结果】
【静态正则表达式方法 匹配切面 例子】
【奔驰车类 BenzCar.java】
package com.Higgin.part5; public class BenzCar {
public void driving(){
System.out.println("benz车行驶.....");
} public void stop(){
System.out.println("benz车停止.....");
} public void sliding(){
System.out.println("benz车漂移.....");
}
}
【前置增强类 】
package com.Higgin.part5; import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice; /**
* 汽车类的前置增强类
*/
public class CarBeforeAdvice implements MethodBeforeAdvice{ @Override
public void before(Method method, Object[] args, Object obj) throws Throwable {
System.out.println("要增强的是:"+obj.getClass()+"类 ---"+method.getName()+"方法"); //得到切点的信息
System.out.println("【前置增强】做好行驶前的准备工作...");
}
}
【Spring的xml匹配 part5.xml】
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 要增强的目标对象1 -->
<bean id="benzTarget" class="com.Higgin.part5.BenzCar"/> <!-- 前置增强 -->
<bean id="drivingBeforeAdvice" class="com.Higgin.part5.CarBeforeAdvice" /> <!-- 正则表达式 匹配 -->
<bean id="regexAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:advice-ref="drivingBeforeAdvice">
<property name="patterns">
<list>
<value>.*ing.*</value>
</list>
</property>
</bean> <!-- Spring代理工厂的成员变量配置 -->
<bean id="benzCar"
class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="regexAdvisor"
p:target-ref="benzTarget"
p:proxyTargetClass="true"
/>
</beans>
【测试类】
package com.Higgin.part5.Test; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.Higgin.part5.BenzCar; public class TestRegexAdvisor {
public static void main(String[] args) {
ApplicationContext context=new ClassPathXmlApplicationContext("part5.xml"); BenzCar benz=(BenzCar) context.getBean("benzCar"); benz.driving(); //匹配.*ing.* System.out.println("==================================="); benz.sliding(); //匹配.*ing.* System.out.println("==================================="); benz.stop(); //不匹配 }
}
【运行结果】
22_AOP_切面——静态切面的更多相关文章
- .Net中的AOP系列之《单元测试切面》
返回<.Net中的AOP>系列学习总目录 本篇目录 使用NUnit编写测试 编写和运行NUnit测试 切面的测试策略 Castle DynamicProxy测试 测试一个拦截器 注入依赖 ...
- Spring AOP 创建切面
增强被织入到目标类的所有方法中,但是如果需要有选择性的织入到目标类某些特定的方法中时,就需要使用切点进行目标连接点的定位.增强提供了连接点方位信息:如织入到方法前面.后面等,而切点进一步描述织 ...
- Java实战之03Spring-03Spring的核心之AOP(Aspect Oriented Programming 面向切面编程)
三.Spring的核心之AOP(Aspect Oriented Programming 面向切面编程) 1.AOP概念及原理 1.1.什么是AOP OOP:Object Oriented Progra ...
- 依赖注入(DI)有助于应用对象之间的解耦,而面向切面编程(AOP)有助于横切关注点与所影响的对象之间的解耦(转good)
依赖注入(DI)有助于应用对象之间的解耦,而面向切面编程(AOP)有助于横切关注点与所影响的对象之间的解耦.所谓横切关注点,即影响应用多处的功能,这些功能各个应用模块都需要,但又不是其主要关注点,常见 ...
- 面向切面编程(Aop)
AOP中的概念 AOP(Aspect Orient Programming),也就是面向切面编程.可以这样理解,面向对象编程(OOP)是从静态角度考虑程序结构,面向切面编程(AOP)是从动态角度考虑程 ...
- spring AOP AspectJ 定义切面实现拦截
总结记录一下AOP常用的应用场景及使用方式,如有错误,请留言. 1. 讲AOP之前,先来总结web项目的几种拦截方式 A: 过滤器 使用过滤器可以过滤URL请求,以及请求和响应的信息,但是过 ...
- SpringMVC---依赖注入与面向切面
1.依赖注入与面向切面 1.1.出现背景 ——如何简化java开发? 其中很重要的一点是“组件化”. ——如何更好的“组件化”? 松耦合,以及尽可能的让组件专注于本身. ——Spring框架的目的也只 ...
- Spring5:面向切面
静态代理 缺点:一个真实角色就会产生一个代理角色,代码量会翻倍! 场景:要在写好的实现方法上加入日志功能(公共功能),不要修改原代码 1:原代码 业务接口: package com.spring; p ...
- Spring 08: AOP面向切面编程 + 手写AOP框架
核心解读 AOP:Aspect Oriented Programming,面向切面编程 核心1:将公共的,通用的,重复的代码单独开发,在需要时反织回去 核心2:面向接口编程,即设置接口类型的变量,传入 ...
随机推荐
- 23.3Sum(三数和为零)
Level: Medium 题目描述: Given an array nums of n integers, are there elements a, b, c in nums such tha ...
- bzoj3098 Hash Killer II 生日共计
题目传送门 题目大意: 让你构造一个字符串,使字符串在题目给出的哈希条件下统计出错. 思路:生日攻击,结论题,尚未理解. #include<bits/stdc++.h> #define C ...
- UESTC - 1610 递推方程+矩阵快速幂
感觉像是HDU Keyboard的加强版,先推出3张牌时的所有组合,然后递推出n张牌 看到n=1e18时吓尿了 最后24那里还是推错了.. (5行1列 dp[1][n],dp[2][n],dp[3][ ...
- 让Nginx支持pathinfo
# 典型配置 location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_ ...
- Hibernate复合主键的注解
[转自] http://blog.csdn.net/happylee6688/article/details/17636801 最近做项目用到了Hibernate框架,采用了纯面向对象的思想,使用OR ...
- ActiveMQ的单节点和集群部署
平安寿险消息队列用的是ActiveMQ. 单节点部署: 下载解压后,直接cd到bin目录,用activemq start命令就可启动activemq服务端了. ActiveMQ默认采用61616端口提 ...
- ABP Zero集成微信小程序登录
首先是ABPZero的第三方登录模块,通过调用第三方的登录接口返回用户信息,再交给ABP的登录验证模块去执行对应的登录注册. 涉及的数据库表主要是这两个表,AbpUsers存储了用户信息,AbpUse ...
- MongoDB数据库进阶 --- 增删查改...
注意: monogdb数据在使用之后必须及时 mongodb.close()否则后台崩溃. 在之前的文章中,我已经介绍了什么事MongoDB以及怎么在windows下安装MongoDB等等基本知识. ...
- 016-hibernateutils模板
package ${enclosing_package}; import org.hibernate.HibernateException; import org.hibernate.Session; ...
- 转-------CNN图像相似度匹配 2-channel network
基于2-channel network的图片相似度判别 原文地址:http://blog.csdn.net/hjimce/article/details/50098483 作者:hjimce 一.相 ...