1、创建切面:
在学习增强时,可能会注意到一个问题:增强被织入到目标类的所有方法中,加入需要有选择性的织入到一个类的某一个方法中,就需要用切点进行目标连接点的定位了。
2、Spring现在支持两种方法匹配器:
2.1、静态方法匹配:匹配器仅对方法名签名(包括方法名和参数类型顺序)进行匹配;
2.2、动态方法匹配:动态方法匹配器会在运行期间检查方法入参的值。
静态方法仅仅只会匹配一次,而动态方法因为每次传入的参数都不同,所以每次都要判断,动态方法对性能影响很大。
3、切点类型:
静态方法切点、动态方法切点、注解切点、表达式切点、流程切点、复合切点。
4、切面类型:
由于增强既包含横切代码,又包含部分的连接点信息,所以可由增强类生成一个切面。切面可以分为几下种:一般切面、切点切面、引介切面。
5、静态普通方法名匹配切面(完整案例):
package com.liu.smart.advice.impl;
/**
* 销售员 只有一个方法 向顾客打招呼
* @author 夏日花语
*/
public class SellerPointCut {
public void greetTo(String name){
System.out.println("亲爱的顾客你好 "+name+" 有什么需要+我是SellerPointOut");
}
}
//----------------------------------------
package com.liu.smart.advice.impl;
/**
* 切面类型的服务员 拥有两个方法 意思打招呼,提供服务。
* @author 夏日花语
*/
public class WaiterPointCut {
public void greetTo(String name){
System.out.println("亲爱的顾客你好 "+name+" 有什么需要+我是WaiterPointOut");
}
public void serveTo(String name){
System.out.println("你需要什么服务"+name+"......我是WaiterPointOut");
}
}
package com.liu.pointcut;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import com.liu.smart.advice.impl.SellerPointCut;
import com.liu.smart.advice.impl.WaiterPointCut;
/**
* 静态普通方法匹配
* @author 夏日花语
*/
public class GreetingAdvicePointCut extends StaticMethodMatcherPointcutAdvisor {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return "greetTo".equals(method.getName());
}
//重写方法getClassFilter
public ClassFilter getClassFilter(){
return new ClassFilter(){
public boolean matches(Class<?> targetClass){
return WaiterPointCut.class.isAssignableFrom(targetClass) ||
SellerPointCut.class.isAssignableFrom(targetClass);
}
};
}
}
package com.liu.pointcut;
import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcutAdvisor;
import com.liu.smart.advice.impl.SellerPointCut;
import com.liu.smart.advice.impl.WaiterPointCut;
/**
* 静态普通方法匹配
* @author 夏日花语
*/
public class GreetingAdvicePointCut extends StaticMethodMatcherPointcutAdvisor {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return "greetTo".equals(method.getName());
}
//重写方法getClassFilter
public ClassFilter getClassFilter(){
return new ClassFilter(){
public boolean matches(Class<?> targetClass){
return WaiterPointCut.class.isAssignableFrom(targetClass) ||
SellerPointCut.class.isAssignableFrom(targetClass);
}
};
}
}
<!-- 创建切 静态方法匹配 -->
<bean id="waiterPointCut" class="com.liu.smart.advice.impl.WaiterPointCut"></bean><!-- 配置服务员类 -->
<bean id="sellerPointCut" class="com.liu.smart.advice.impl.SellerPointCut"></bean><!-- 配置销售员类 -->
<bean id="greetingBeforePointCut" class="com.liu.advice.GreetingBeforePointCut"></bean><!-- 配置增强类 -->
<bean id="greetingAdvicePointCut" class="com.liu.pointcut.GreetingAdvicePointCut">
<property name="advice" ref="greetingBeforePointCut"></property><!-- 向切面注入一个前置增强 -->
</bean>
<bean id="parent" class="org.springframework.aop.framework.ProxyFactoryBean" abstract="true">
<property name="interceptorNames" value="greetingAdvicePointCut"></property>
<property name="proxyTargetClass" value="true"></property>
</bean>
<bean id="waiterPoint" parent="parent" p:target-ref="waiterPointCut"></bean>
<bean id="sellerPoint" parent="parent" p:target-ref="sellerPointCut"></bean>
package com.liu.action;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.liu.smart.advice.impl.SellerPointCut;
import com.liu.smart.advice.impl.WaiterPointCut;
/**
* 测试类
* @author 夏日花语
com.liu.smart.advice.impl.WaiterPointCut.greetTo
how are you! Mr 我是猪
亲爱的顾客你好 我是猪 有什么需要+我是WaiterPointOut
com.liu.smart.advice.impl.SellerPointCut.greetTo
how are you! Mr 我是人
亲爱的顾客你好 我是人 有什么需要+我是SellerPointOut
你需要什么服务我是神......我是WaiterPointOut
*/
public class PointCut {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
WaiterPointCut waiterPointCut = (WaiterPointCut) context.getBean("waiterPoint");
SellerPointCut sellerPointCut = (SellerPointCut) context.getBean("sellerPoint");
waiterPointCut.greetTo("我是猪");
sellerPointCut.greetTo("我是人");
waiterPointCut.serveTo("我是神");
}
}
6、静态正则表达式:
<bean id="regexpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="greetingBeforePointCut"></property><!-- 向切面注入一个前置增强 -->
<property name="patterns"><!-- 用正则表达式定义目标类 -->
<list>
<value>.*greet.*</value><!-- 匹配模式串 -->
</list>
</property>
</bean>
<bean id="pointCut" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames" value="regexpAdvisor"></property><!-- 指定匹配的方法 静态正则表达式方法 -->
<property name="target">
<ref local="sellerPointCut"/>
</property><!-- 指定目标类 -->
<property name="proxyTargetClass" value="true"></property>
</bean>