Spring AOP 创建切面
1、切点类型
package com.yyq.aop;
public class Waiter {
public void greetTo(String name) {
System.out.println("waiter greet to " + name + ".");
}
public void serveTo(String name) {
System.out.println("waiter serving to " + name + ".");
}
}
Seller业务类:
package com.yyq.aop;
public class Seller {
public void greetTo(String name) {
System.out.println("seller greet to " + name + ".");
}
}
GreetingAdvisor切面实现类:
package com.yyq.aop;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import java.lang.reflect.Method;
public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor {
@Override
public boolean matches(Method method, Class<?> aClass) {
return "greetTo".equals(method.getName());
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
@Override
public boolean matches(Class<?> aClass) {
return Waiter.class.isAssignableFrom(aClass);
}
};
}
}
GreetingBeforeAdvice前置增强实现类:
package com.yyq.aop;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class GreetingBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println(o.getClass().getName() + "." + method.getName());
String clientName = (String) objects[0];
System.out.println("Hi! Mr." + clientName + ".");
}
}
配置切面:静态方法配置切面
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="waiterTarget" class="com.yyq.aop.Waiter"/>
<bean id="sellerTarget" class="com.yyq.aop.Seller"/>
<bean id="greetingAdvice" class="com.yyq.aop.GreetingBeforeAdvice"/>
<bean id="greetingAdvisor" class="com.yyq.aop.GreetingAdvisor" p:advice-ref="greetingAdvice"/> <bean id="parent" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="greetingAdvisor"
p:proxyTargetClass="true"/>
<bean id="waiter" parent="parent" p:target-ref="waiterTarget"/>
<bean id="seller" parent="parent" p:target-ref="sellerTarget"/>
</beans>
测试方法:
@Test
public void testAdvisor(){
String configPath = "com\\yyq\\aop\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter");
Seller seller = (Seller)ctx.getBean("seller");
waiter.greetTo("John");
waiter.serveTo("John");
seller.greetTo("John");
}
<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"
p:advice-ref="greetingAdvice">
<property name="patterns">
<list>
<value>.*greet.*</value>
</list>
</property>
</bean>
<bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="regexpAdvisor"
p:target-ref="waiterTarget"
p:proxyTargetClass="true"/>
测试方法:
@Test
public void testAdvisor2(){
String configPath = "com\\yyq\\aop\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter1");
waiter.greetTo("John");
waiter.serveTo("John");
}
package com.yyq.aop;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.DynamicMethodMatcherPointcut;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class GreetingDynamicPointcut extends DynamicMethodMatcherPointcut {
private static List<String> specialClientList = new ArrayList<String>();
static {
specialClientList.add("John");
specialClientList.add("Tom");
}
public ClassFilter getClassFilter() {
return new ClassFilter() {
@Override
public boolean matches(Class<?> aClass) {
System.out.println("调用getClassFilter()对" + aClass.getName() + "做静态检查。");
return Waiter.class.isAssignableFrom(aClass);
}
};
}
public boolean matches(Method method, Class clazz) {
System.out.println("调用matches(method,clazz)" + clazz.getName() + "." + method.getName() + "做静态检查。");
return "greetTo".equals(method.getName());
}
@Override
public boolean matches(Method method, Class<?> aClass, Object[] objects) {
System.out.println("调用matches(method,aClass)" + aClass.getName() + "." + method.getName() + "做动态检查。");
String clientName = (String)objects[0];
return specialClientList.contains(clientName);
}
}
Spring动态检查机制:在创建代理时对目标类的每个连接点使用静态切点检查,如果仅通过静态切点检查就可以知道连接点是不匹配的,则在运行时就不再进行动态检查了;如果静态切点检查时匹配的,在运行时才进行动态切点检查。
<bean id="dynamicAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="com.yyq.aop.GreetingDynamicPointcut"/>
</property>
<property name="advice">
<bean class="com.yyq.aop.GreetingBeforeAdvice"/>
</property>
</bean>
<bean id="waiter2" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="dynamicAdvisor"
p:target-ref="waiterTarget"
p:proxyTargetClass="true"/>
测试方法:
@Test
public void testAdvisor3(){
String configPath = "com\\yyq\\aop\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter2");
waiter.serveTo("Peter");
waiter.greetTo("Peter");
waiter.serveTo("John");
waiter.greetTo("John");
}
package com.yyq.aop;
public class WaiterDelegate {
private Waiter waiter;
public void service(String clientName){
waiter.greetTo(clientName);
waiter.serveTo(clientName);
}
public void setWaiter(Waiter waiter){
this.waiter = waiter;
}
}
配置控制流程切面:
<bean id="controlFlowPointcut" class="org.springframework.aop.support.ControlFlowPointcut">
<constructor-arg type="java.lang.Class" value="com.yyq.aop.WaiterDelegate"/>
<constructor-arg type="java.lang.String" value="service"/>
</bean>
<bean id="controlFlowAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
p:pointcut-ref="controlFlowPointcut"
p:advice-ref="greetingAdvice"/>
<bean id="waiter3" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="controlFlowAdvisor"
p:target-ref="waiterTarget"
p:proxyTargetClass="true"/>
测试方法:
@Test
public void testAdvisor4(){
String configPath = "com\\yyq\\aop\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter3");
WaiterDelegate wd = new WaiterDelegate();
wd.setWaiter(waiter);
waiter.serveTo("Peter");
waiter.greetTo("Peter");
wd.service("Peter");
}
package com.yyq.aop;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.ComposablePointcut;
import org.springframework.aop.support.ControlFlowPointcut;
import org.springframework.aop.support.NameMatchMethodPointcut;
public class GreetingComposablePointcut {
public Pointcut getIntersectionPointcut(){
ComposablePointcut cp = new ComposablePointcut();
Pointcut pt1 = new ControlFlowPointcut(WaiterDelegate.class,"service");
NameMatchMethodPointcut pt2 = new NameMatchMethodPointcut();
pt2.addMethodName("greetTo");
return cp.intersection(pt1).intersection((Pointcut)pt2);
}
}
配置复合切点切面:
<bean id="gcp" class="com.yyq.aop.GreetingComposablePointcut"/>
<bean id="composableAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"
p:pointcut="#{gcp.intersectionPointcut}"
p:advice-ref="greetingAdvice"/>
<bean id="waiter4" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="composableAdvisor"
p:target-ref="waiterTarget"
p:proxyTargetClass="true"/>
测试方法:
@Test
public void testAdvisor5(){
String configPath = "com\\yyq\\aop\\beans.xml";
ApplicationContext ctx = new ClassPathXmlApplicationContext(configPath);
Waiter waiter = (Waiter)ctx.getBean("waiter4");
WaiterDelegate wd = new WaiterDelegate();
wd.setWaiter(waiter);
waiter.serveTo("Peter");
waiter.greetTo("Peter");
wd.service("Peter");
}
<bean id="introduceAdvisor"
class="org.springframework.aop.support.DefaultIntroductionAdvisor">
<constructor-arg>
<bean class="com.yyq.advice.ControllablePerformanceMonitor" />
</constructor-arg>
</bean>
<bean id="forumServiceTarget" class="com.yyq.advice.ForumService" />
<bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean"
p:interceptorNames="introduceAdvisor"
p:target-ref="forumServiceTarget"
p:proxyTargetClass="true"/>
Spring AOP 创建切面的更多相关文章
- 详细解读 Spring AOP 面向切面编程(二)
本文是<详细解读 Spring AOP 面向切面编程(一)>的续集. 在上篇中,我们从写死代码,到使用代理:从编程式 Spring AOP 到声明式 Spring AOP.一切都朝着简单实 ...
- spring AOP面向切面编程学习笔记
一.面向切面编程简介: 在调用某些类的方法时,要在方法执行前或后进行预处理或后处理:预处理或后处理的操作被封装在另一个类中.如图中,UserService类在执行addUser()或updateUse ...
- 【spring-boot】spring aop 面向切面编程初接触--切点表达式
众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...
- 【spring-boot】spring aop 面向切面编程初接触
众所周知,spring最核心的两个功能是aop和ioc,即面向切面,控制反转.这里我们探讨一下如何使用spring aop. 1.何为aop aop全称Aspect Oriented Programm ...
- 【Spring系列】Spring AOP面向切面编程
前言 接上一篇文章,在上午中使用了切面做防重复控制,本文着重介绍切面AOP. 在开发中,有一些功能行为是通用的,比如.日志管理.安全和事务,它们有一个共同点就是分布于应用中的多处,这种功能被称为横切关 ...
- 从源码入手,一文带你读懂Spring AOP面向切面编程
之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...
- Spring AOP 面向切面编程入门
什么是AOP AOP(Aspect Oriented Programming),即面向切面编程.众所周知,OOP(面向对象编程)通过的是继承.封装和多态等概念来建立一种对象层次结构,用于模拟公共行为的 ...
- 详细解读 Spring AOP 面向切面编程(一)
又是一个周末, 今天我要和大家分享的是 AOP(Aspect-Oriented Programming)这个东西,名字与 OOP 仅差一个字母,其实它是对 OOP 编程方式的一种补充,并非是取而代之. ...
- 阿里四面:你知道Spring AOP创建Proxy的过程吗?
Spring在程序运行期,就能帮助我们把切面中的代码织入Bean的方法内,让开发者能无感知地在容器对象方法前后随心添加相应处理逻辑,所以AOP其实就是个代理模式. 但凡是代理,由于代码不可直接阅读,也 ...
随机推荐
- 典型用户 persona
persona 典型用户 1.姓名:王涛 2.年龄:22 3.收入:基本无收入 4.代表用户在市场上的比例和重要性:王涛为铁道学生.本软件的用户主要是学生和老师,尤其是广大的铁大学子,所以此典型用户的 ...
- mui开发webapp(2)
前端开发APP,从HBuilder开始~ 序 通过 HTML5 开发移动App 时,会发现HTML5 很多能力不具备.为弥补HTML5 能力的不足,在W3C 中国的指导下成立了www.HTML5Plu ...
- 撸一撸腾讯的微信支付(C#)
一.前言 以往网上支付都是支付宝的天下,随着微信用户群的日益增多(其实,到现在我也不理解微信为嘛那么火,功能还没QQ强大,或许是公众号的原因?),先如今不上个微信支付你都不好意思说你系统支持在线支付. ...
- C语音的调查
1.你对自己的未来有什么规划?做了哪些准备? 很迷茫吧.尽力做好该做的事情.希望认真学习代码,毕竟是专业课 2.你认为什么是学习?学习有什么用?现在学习动力如何?为什么? 学习有很多啊,不论是课堂上, ...
- 装载:对CSS中的Position、Float属性的一些深入探讨
对CSS中的Position.Float属性的一些深入探讨 对CSS中的Position.Float属性的一些深入探讨 对于Position.Float我们在平时使用上可以说是使用频率非常高的两个 ...
- O(V*n)的多重背包问题
多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Ma ...
- 【BZOJ】【3790】神奇项链
Manacher算法/DP 找出所有的回文串,看做是一个个线段,那么问题就转化成了用最少的线段将整个区间覆盖起来,可以重叠,那么这就是一个DP了= = Orz ZKY大爷,让蒟蒻开眼界了……头一次知道 ...
- c3p0 --2
c3p0号称是java界最好的数据池. c3p0的配置方式分为三种,分别是 1.setters一个个地设置各个配置项 2.类路径下提供一个c3p0.properties文件 3.类路径下提供一个c3p ...
- 如何用 Parse 和 Swift 搭建一个像 Instagram 那样的应用?(2)
[编者按]本篇文章作者是 Reinder de Vries,既是一名企业家,也是优秀的程序员,发表多篇应用程序的博客.本篇文章中,作者主要介绍了如何基于 Parse 特点,打造一款类似 Instagr ...
- Nginx状态监控
通过配置nginx.conf文件来实现对Nginx状态信息的监控. 1.配置nginx.conf vim /usr/local/nginx/conf/nginx.conf 再server块配置项中添加 ...