<bean id="dynamicAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.advisor.GreetingDynamicPointcut"></bean>
</property>
<property name="advice">
<bean class="org.advisor.GreetingBeforeAdvice"></bean>
</property>
</bean>
<bean id="waiter2" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<idref local="dynamicAdvisor" />
</property>
<property name="proxyTargetClass" value="true"></property>
<property name="target" ref="waiterTarget"></property>
</bean>
private static List<String> specialClientList = new ArrayList<String>(); static{ specialClientList.add("John"); //Java虛拟機調用的時候運作 specialClientList.add("Tom"); } public ClassFilter getClassFilter() { return new ClassFilter(){ public boolean matches(Class clazz) { // TODO Auto-generated method stub System.out.println("調用getClassFilter對"+clazz.getName()+"做靜态檢查."); return Waiter.class.isAssignableFrom(clazz); } }; }
昨天晚上沒時間總結今天一塊補上吧……
對切面有了更深的了解,以前隻知道老師講的通知advice和pointcut兩種簡單的加入切面的方法。
通知advice直接作為切面的執行位置和執行代碼,沒有指定切入點,即對ProxyFactoryBean代理的所有的bean進行代碼織入。
pointcut通過NameMatchMethodPointcutAdvisor切面類
<property name="mappedName">
<value>helloM*</value>
</property>
<property name="advice">
<ref bean="logBeforeAdvice" />
</property>//通過mappeName指定切點,通過advice指定執行點位置和執行點方法進行織入。
新學的切面:靜态切面:切面類需要自己定義繼承StaticMethodMatcherPointcutAdvisor
上面的類定義了切點需要在spring配置檔案裡對這個切面配置增強,
public boolean matches(Method method, Class clazz) {
// TODO Auto-generated method stub
return "greetTo".equals(method.getName()); //切點方法比對規則:方法名為greetTo
}
@Override
public ClassFilter getClassFilter() {
// TODO Auto-generated method stub
return new ClassFilter(){
public boolean matches(Class clazz) {
// TODO Auto-generated method stub
return Waiter.class.isAssignableFrom(clazz); //切點類比對規則為waiter的類或者子類
}
};
}
<!-- 靜态切面 -->
<bean id="greetingAdvisor" class="org.advisor.GreetingAdvisor">
<property name="advice" ref="greetingAdvice"></property>
</bean>//增強
<bean id="parent" abstract="true"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames">
<list>
<value>greetingAdvisor</value>
</list>
</property>
<property name="proxyTargetClass" value="true"></property> //使用CGLib對類進行代理
</bean>//自定義靜态切面類
<bean id="waiter" parent="parent">
<property name="target" ref="waiterTarget"></property>
</bean>
這裡不能用JVM的動态代理來代理 因為JVM隻能代理接口。
動态切面:實作DynamicMethodMatcherPointcut類
@Override
public boolean matches(Method method, Class clazz) {
// TODO Auto-generated method stub
System.out.println("調用matches(Method ,Class)對"+clazz.getName()+"做靜态檢查.");
return "greetTo".equals(method.getName());
}
public boolean matches(Method method, Class clazz, Object[] args) {
// TODO Auto-generated method stub
System.out.println("調用 matches(Method ,Class, Object[])"+ clazz.getName()+"."+method.getName()+"做動态檢查");
String clientName = (String)args[0];
return specialClientList.contains(clientName);
}
spring配置檔案
動态切面先通過靜态類中方法進行判斷,以後再不進行判斷。
流切面:
<bean id="controlFlowAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.ControlFlowPointcut">
<constructor-arg type="java.lang.Class" value="org.advisor.WaiterDelegate"></constructor-arg>
<constructor-arg type="java.lang.String" value="service"></constructor-arg>
</bean> //當将waiterDelegate中的waiter屬性設定為waiter3調用service方法調用waiter3中的方時
</property> //将被織入代碼
<property name="advice">
<bean class="org.advisor.GreetingBeforeAdvice"></bean>
</property>
</bean>
<bean id="waiter3" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interceptorNames"> //擷取waiter3bean并調用方法将不會織入代碼
<idref local="controlFlowAdvisor" />
</property>
<property name="proxyTargetClass" value="true"></property>
<property name="target">
<bean class="org.advisor.Waiter"></bean>
</property>
</bean>
唉……昨天的還沒總結完,看來今天學的得明天總結了,又要停電了…………