<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>
唉……昨天的还没总结完,看来今天学的得明天总结了,又要停电了…………