连接点:
程序执行的摸个特定位置,如类开始初始化之前、类初始化之后、类中某个方法调用前和调用后,方法抛出异常后等等都是 连接点。但是Spring只支持方法的连接点,所以仅能在方法调用前,调用后,抛出异常后植入增强。
切点:
通过数据库查询的概念来理解切点和连接点的关系在合适不过了:连接点相当于数据库中的记录,而切点相当于查询条件。切 点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
增强:
增强时植入目标类连接点上的一段代码。
切点加上增强就是切面,就是包含了需要植入的代码以及植入的位置信息。
1.编写需要植入逻辑的代码
首先编写一个Waiter类,它有两个方法,greetTo和serveTo;然后编写一个Seller类,它也有一个greetTo方法。
Waiter类
public class Waiter { public void greetTo(String name){ System.out.println("waiter greet to :"+name); } public void serveTo(String name){ System.out.println("waiter serve to :"+name); } }
Seller类
public class Seller { public void greetTo(String name){ System.out.println("seller greet to :"+name); } }
2.编写需要植入的逻辑即增强
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class RoundGreeting implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { Object[] args = methodInvocation.getArguments(); String name = (String) args[0]; System.out.println("how are you :Mr"+name); Object obj = methodInvocation.proceed(); System.out.println("Please enjoy yourself!"); return obj; } }
3.定义一个切面,可以通过类,方法名,以及方法方位等信息灵活的定义切面的连接点(即添加增强的地方)
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()); } @Override public ClassFilter getClassFilter() { return new ClassFilter() { @Override public boolean matches(Class<?> aClass) { return Waiter.class.isAssignableFrom(aClass); } }; } }
4.在xml文件中定义各种Bean
<?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.xsd"> <bean id="waiter" class="aspect.Waiter"/> <bean id="seller" class="aspect.Seller"/> <bean id="advice" class="aspect.RoundGreeting"/> <bean id="advisor" class="aspect.GreetingAdvisor" p:advice-ref="advice" /> <bean id="parent" abstract="true" class="org.springframework.aop.framework.ProxyFactoryBean" p:interceptorNames="advisor" p:proxyTargetClass="true" /> <bean id="proxyWaiter" parent="parent" p:target-ref="waiter" /> <bean id="proxySeller" parent="parent" p:target-ref="seller" /> </beans>