增强被织入目标类的所有方法中,假设希望有选择的织入目标类的某些特定方法中,就需要使用切点进行目标连接点的定位了
切点进一步描述织入哪些类的哪些方法上
仅有切点,无法制作出一个切面,必须结合增强才行
1、切点类型
1)静态方法切点:org.springframework.aop.support.StaticMethodMatcherPointcut 是静态方法切点的抽象基类,默认情况下它匹配所有的类。StaticMethodMatcherPointcut包括两个主要的子类,分别是 NameMatchMethodPointcut和AbstractRegexpMethodPointcut,前者提供简单字符串匹配方法签名,而后者 使用正则表达式匹配方法签名。
2)动态方法切点:org.springframework.aop.support.DynamicMethodMatcherPointcut 是动态方法切点的抽象基类,默认情况下它匹配所有的类。DynamicMethodMatcherPointcut类已经过时,可以使用 DefaultPointcutAdvisor 和DynamicMethodMatcherPointcut动态方法匹配器替代之。
3)注解切点:org.springframework.aop.support.AnnotationMatchingPointcut实现类表示注解切点。使用AnnotationMatchingPointcut支持在Bean中直接通过JDK5.0注解标签定义的切点。
4)表达式切点:org.springframework.aop.support.ExpressionPointcut接口主要是为了支持AspectJ切点表达式语法而定义的接口。
5)流程切点:org.springframework.aop.support.ControlFlowPointcut 实现类表示控制流程切点。ControlFlowPointcut是一种特殊的切点,它根据程序执行堆栈的信息查看目标方法是否由某一个方法直接或间接发 起调用,以此判断是否为匹配的连接点。
6)复合切点:org.springframework.aop.suppot.ComposablePointcut实现类是为创建多个切点而提供的方便操作类。它所有的方法都返回ComposablePointcut类,这样,我们就可以使用连接表达式对切点进行操作。
2、切面类型
Spring使用org.springframework.aop.Advisor接口表示切面的概念,一个切面同时包含横切代码和连接点信息。切面可以分为三类:一般切面、切点切面和引介切面。
1)Advisor:代表一般切面,它仅包含一个Advice。由于Advice包含了横切代码和连接点的信息,所以Advice本身就是一个简单的切面,只不过它代表的横切的连接点是所有目标类的所有方法,因为这个横切面太宽泛,所以一般不会直接使用。
2)PointcutAdvisor:代表具有切点的切面,它包含Advice和Pointcut两个类,这样,我们就可以通过类、方法名以及方法方位等信息灵活地定义切面的连接点,提供更具适用性的切面。
3)IntroductionAdvisor:代表引介切面,引介切面是对应引介增强的特殊的切面,它应用于类层面上,所以引介切面适用ClassFilter进行定义。
PointcutAdvisor主要有6个具体的实现类:
1)DefaultPointcutAdvisor:最常用的切面类型,它可以通过任意Pointcut和Advice定义一个切面,唯一不支持的是引介的切面类型,一般可以通过扩展该类实现自定义的切面。
2)NameMatchMethodPointcutAdvisor:通过该类可以定义按方法名定义切点的切面。
3)RegexpMethodPointcutAdvisor:允许用户以正则表达式模式串定义方法匹配的切点。
4)StaticMethodMatcherPointcutAdvisor:静态方法匹配器切点定义的切面,默认情况下,匹配所有的目标类。
5)AspectJExpressionPointcutAdvisor:用于AspectJ切点表达式定义切点的切面,它是Spring 2.0 新提供的类。
6)AspectJPointcutAdvisor:用于AspectJ语法定义切点的切面,它也是Spring 2.0 新提供的类。
静态普通方法名匹配切面
1 package com.asm; 2 //业务类 3 public class Waiter1 { 4 5 public void greetTo(String name) { 6 System.out.println("waiter greet to " + name + "..."); 7 } 8 9 public void serveTo(String name) { 10 System.out.println("waiter serving " + name + "..."); 11 } 12 }
//业务类
1 public class Sheer { 2 public void greetTo(String name) { 3 System.out.println("seller greet to " + name + "..."); 4 } 5 }
1 public class GreetingAdvisor extends StaticMethodMatcherPointcutAdvisor { 2 3 //切点方法匹配方法名 4 public boolean matches(Method method, Class clazz) { 5 return "greetTo".equals(method.getName()); 6 } 7 8 //切点类匹配,为Waiter的子类 9 public ClassFilter getClassFilter() { 10 return new ClassFilter() { 11 public boolean matches(Class clazz) { 12 return Waiter1.class.isAssignableFrom(clazz); 13 } 14 }; 15 } 16 17 18 }
1 package com.asm; 2 3 import java.lang.reflect.Method; 4 5 import org.springframework.aop.MethodBeforeAdvice; 6 7 public class GreetingBeforeAdvice1 implements MethodBeforeAdvice { 8 9 public void before(Method method, Object[] args, Object obj) throws Throwable { 10 String clientName = (String) args[0]; 11 System.out.println(obj.getClass().getName() + "." + method.getName()); 12 System.out.println("How are you!Mr." + clientName + "."); 13 } 14 }
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-3.1.xsd 10 http://www.springframework.org/schema/tx 11 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> 14 15 <!-- 扫描类包下的类 这样Spring定义的注解才能产生作用 16 如@Resposity @Autowired 17 --> 18 <bean id="waiterTarget" class="com.asm.Waiter1"></bean> 19 <bean id="sellerTarget" class="com.asm.Sheer"></bean> 20 21 <bean id="greetingAdvice" class="com.asm.GreetingBeforeAdvice1"></bean> 22 <bean id="greetingAdvisor" class="com.asm.GreetingAdvisor" 23 p:advice-ref="greetingAdvice"/>//想切面注入一个前置增强, 24 25 <bean id="parent" abstract="true" //通过一个父bean定义公共的配置信息 26 class="org.springframework.aop.framework.ProxyFactoryBean" 27 p:interceptorNames="greetingAdvisor" 28 p:proxyTargetClass="true"/> 29 30 <bean id="waiter" parent="parent" p:target-ref="waiterTarget" /> 31 <bean id="seller" parent="parent" p:target-ref="sellerTarget" /> 32 33 </beans>
1 package com.asm; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 import org.testng.annotations.Test; 6 7 public class SpringTest1 { 8 9 public static void main(String[] args) { 10 11 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 12 Waiter1 waiter = (Waiter1)ctx.getBean("waiter"); 13 Sheer sheer = (Sheer)ctx.getBean("seller"); 14 waiter.greetTo("join"); 15 waiter.serveTo("join"); 16 sheer.greetTo("join"); 17 } 18 }
打印信息:
1 com.asm.Waiter1.greetTo 2 How are you!Mr.join. 3 waiter greet to join... 4 waiter serving join... 5 seller greet to join...
静态正则表达式方法匹配切面
1 public class Waiter1 { 2 public void greetTo(String name) { 3 System.out.println("waiter greet to " + name + "..."); 4 } 5 6 public void serveTo(String name) { 7 System.out.println("waiter serving " + name + "..."); 8 } 9 }
1 public class GreetingBeforeAdvice1 implements MethodBeforeAdvice{ 2 public void before(Method method, Object[] args, Object obj) 3 throws Throwable { 4 String clientName = (String) args[0]; 5 System.out.println(obj.getClass().getName() + "." + method.getName()); 6 System.out.println("How are you!Mr." + clientName + "."); 7 } 8 }
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 8 http://www.springframework.org/schema/context 9 http://www.springframework.org/schema/context/spring-context-3.1.xsd 10 http://www.springframework.org/schema/tx 11 http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 12 http://www.springframework.org/schema/aop 13 http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> 14 15 <!-- 普通方法名匹配切面 --> 16 <bean id="waiterTarget" class="com.asm.Waiter1" /> 17 <bean id="greetingAdvice" class="com.asm.GreetingBeforeAdvice1" /> 18 19 20 21 <!-- 正则表达式方法名匹配切面 --> 22 <bean id="regexpAdvisor" 23 class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" 24 p:advice-ref="greetingAdvice"> 25 <property name="patterns"> 26 <list> 27 <value>.*greet.*</value> 28 </list> 29 </property> 30 </bean> 31 <bean id="waiter1" class="org.springframework.aop.framework.ProxyFactoryBean" 32 p:interceptorNames="regexpAdvisor" p:target-ref="waiterTarget" 33 p:proxyTargetClass="true" /> 34 35 </beans>
1 package com.asm; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class SpringTest1 { 7 public static void main(String[] args) { 8 9 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml"); 10 Waiter1 waiter = (Waiter1)ctx.getBean("waiter1"); 11 waiter.greetTo("join"); 12 waiter.serveTo("join"); 13 } 14 }
浙公网安备 33010602011771号