一、基本概念
切面(aspect):用来切插业务方法的类。
连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析。
通知(advice):在切面类中,声明对业务方法做额外处理的方法。
切入点(pointcut):业务类中指定的方法,作为切面切入的点。其实就是指定某个方法作为切面切的地方。
目标对象(target object):被代理对象。
AOP代理(aop proxy):代理对象。
通知:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知。
二、例子
首先我们来看看一个简单的使用Spring AOP的例子
1.接口Person
public interface Person { public void sayHello() ; }
2.实现类Student,实现了Person接口,也是我们这里的目标类(被代理类)
public class Student implements Person { @Override public void sayHello() { System.out.println("I am a student~"); } }
3.通知类(提供方法增强的逻辑)
//方法调用前的增强(实现了MethodBeforeAdvice) public class BeforeMethod implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("this is before method!!!"); } }
//方法返回后的增强(实现了AfterReturningAdvice) public class AfterMethod implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("this is after return!!! how?"); } }
4.切点实现(决定Advice通知应该作用于哪个连接点)
public class MyPointCut extends NameMatchMethodPointcut { private static final long serialVersionUID = -164470606471336765L; //作用于所有方法 @Override public boolean matches(Method method, @SuppressWarnings("rawtypes") Class targetClass) { return true; } }
6.配置信息
<?xml version="1.0" encoding="GB2312"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" default-autowire="byName"> <!-- 业务类 --> <bean id="student" class="org.learn.aop.Student"></bean> <!-- 通知类 --> <bean id="beforeMethod" class="org.learn.aop.BeforeMethod"></bean> <bean id="afterMethod" class="org.learn.aop.AfterMethod"></bean> <!-- PointCut --> <bean id="myPointCut" class="org.learn.aop.MyPointCut"></bean> <!-- Advisor --> <bean id="myAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut"> <ref bean="myPointCut"/> </property> <property name="advice"> <ref bean="beforeMethod"/> </property> </bean> <!-- ProxyFactoryBean --> <bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>org.learn.aop.Person</value> </property> <property name="target"> <ref bean="student"/> </property> <property name="interceptorNames"> <list> <value>myAdvisor</value> <!-- 如果这里给的是advice,那么将被封装成一个advisor,其中pointcut采用默认实现--> <value>afterMethod</value> </list> </property> </bean> </beans>
7.测试
public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("org/learn/aop/AOPLearn.xml"); Person student = (Person) context.getBean("proxyFactoryBean"); student.sayHello(); }
8.结果
this is before method!!! I am a student~ this is after return!!! how?