Spring Advice
Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点。简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后添加额外的功能。
在Spring AOP中,有 4 种类型通知(advices)的支持:
-
通知(Advice)之前 - 该方法执行前运行
- 通知(Advice)返回之后 – 运行后,该方法返回一个结果
- 通知(Advice)抛出之后 – 运行方法抛出异常后,
- 环绕通知 – 环绕方法执行运行,结合以上这三个通知。
下面的例子显示Spring AOP 通知如何工作。
接口
public interface UserService { public void addUser(); public String eat(); }
实现类
public class UserServiceImpl implements UserService { public void addUser() { System.out.println("添加用户"); } public String eat() { String some="apple"; System.out.println("eat a little apple"); return some; } }
前置增强
public class BeforeAdvice implements MethodBeforeAdvice { /** * * @param method 目标方法 * @param objects 目标方法的参数列表 * @param o 目标对象 * @throws Throwable */ public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("前置增强---------------"); } }
后置增强
public class AfterAdvice implements AfterReturningAdvice { public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable { System.out.println("后置增强"); } }
环绕增强 (出现在前置增强之后 ,后置增强之前)
public class AroundAdvice implements MethodInterceptor { /** * * @param methodInvocation * @return * @throws Throwable */ public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("执行方法之前的环绕 通知"); Object result = methodInvocation.proceed();//方法的执行 主业务的执行 if(result!=null){ result="小黑"; } System.out.println("执行方法之后的环绕 通知"); return result; } }
ApplicationContext.xml
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!--目标对象--> <bean id ="userservice" class="cn.kitty.service.UserServiceImpl"></bean> <!--配置前置通知--> <bean id="beforeAdvice" class="cn.kitty.service.BeforeAdvice"></bean> <!--配置后置通知--> <bean id="afterAdvice" class="cn.kitty.service.AfterAdvice"></bean> <!--配置环绕通知--> <bean id="aroundAdrice" class="cn.kitty.service.AroundAdvice"></bean> <!-- 配置代理工厂bean 生成代理类 把通知织入到目标对象--> <bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!--注册目标对象--> <property name="targetName" value="userservice"></property> <!--注册通知--> <property name="interceptorNames" > <array> <value>beforeAdvice</value> <value>afterAdvice</value> <value>aroundAdrice</value> </array> </property> </bean> </beans>
test 类
public class Test1011 { @Test public void yichang(){ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); UserService service= (UserService) context.getBean("userProxy"); service.addUser(); System.out.println("---------------"); service.eat(); } @Test public void around(){ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); UserService service= (UserService) context.getBean("userProxy"); service.addUser(); System.out.println("---------------"); service.eat(); } @Test public void before(){ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); UserService service= (UserService) context.getBean("userProxy"); service.addUser(); System.out.println("---------------"); service.eat(); } @Test public void after(){ ApplicationContext context=new ClassPathXmlApplicationContext("ApplicationContext.xml"); UserService service= (UserService) context.getBean("userProxy"); service.addUser(); System.out.println("---------------"); service.eat(); } }