Spring学习笔记04-AOP(一)
一、AOP的使用(步骤分析)
1、加入jar包
2、在配置文件中加入aop的命名空间
3、基于注解的方式
① 在配置文件中加入如下配置
② 把横切关注点的代码抽象到切面的类中
a、切面首先是一个 IOC 中的 bean,即加入@Component 注解
b、切面还需要加入@Aspect 注解
③ 在类中声明各种通知
a、声明一个方法
b、在方法前加入各方法的注解,如:@Before
④ 可以在通知方法中声明一个类型为JoinPoint的参数,然后就能访问链接细节,如方法名称和参数值。
二、实例代码
package aop; public interface Yunsuan { int add(int i,int j); int sub(int i,int j); int mul(int i,int j); int div(int i,int j); }
package aop; import org.springframework.stereotype.Component; @Component public class YunsuanImpl implements Yunsuan { @Override public int add(int i, int j) { //System.out.println("begin"+i+","+j); int result=i+j; //System.out.println("end"+result); return result; } @Override public int sub(int i, int j) { //System.out.println("begin"+i+","+j); int result=i-j; //System.out.println("end"+result); return result; } @Override public int mul(int i, int j) { //System.out.println("begin"+i+","+j); int result=i*j; //System.out.println("end"+result); return result; } @Override public int div(int i, int j) { //System.out.println("begin"+i+","+j); int result=i/j; //System.out.println("end"+result); return result; } }
package aop; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext c=new ClassPathXmlApplicationContext("aop.xml"); Yunsuan yunsuan=c.getBean(Yunsuan.class); int result=yunsuan.add(3, 4); System.out.println("result="+result); int re=yunsuan.div(3, 4); System.out.println("result="+re); } }
<?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" xmlns:context="http://www.springframework.org/schema/context" 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-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 配置自动扫描的包 --> <context:component-scan base-package="aop"></context:component-scan> <!--使AspjectJ注解起作用:自动为匹配的类生成代理对象 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
package aop; import java.util.Arrays; import java.util.List; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; //把这个类声明为一个切面,放到IOC容器,再声明为一个切面 @Aspect @Component public class Qiemian { //声明该方法是一个前置通知 //@Before("execution(public int aop.Yunsuan.*(int,int))") //@Before("execution(* aop.*.*(int,int))") @Before("execution(* aop.*.*(..))") public void before(JoinPoint joinpoint) { String name=joinpoint.getSignature().getName(); List<Object> args=Arrays.asList(joinpoint.getArgs()); System.out.println(name+" begin "+args); } //后置通知,目标方法执行后(无论异常) @After("execution(* aop.*.*(..))") public void after(JoinPoint joinpoint) { String name=joinpoint.getSignature().getName(); //不能返回目标方法执行的结果 //List<Object> args=Arrays.asList(joinpoint.getArgs()); System.out.println(name+" end "); } //返回通知,在方法正常结束后执行,,可以访问到方法的返回值 @AfterReturning(value="execution(* aop.*.*(..))", returning="result") public void afterReturning(JoinPoint joinpoint,Object result) { String name=joinpoint.getSignature().getName(); System.out.println(name+" end with " + result); } //异常通知,在方法出现异常时执行,可以访问到异常对象 @AfterThrowing(value="execution(* aop.*.*(..))", throwing="e") public void afterThrowing(JoinPoint joinpoint,Exception e) { String name=joinpoint.getSignature().getName(); System.out.println(name+" exception " + e); } //环绕通知,需携带ProceedingJoinPoint类型的参数,必须有返回值 @Around("execution(* aop.*.*(..))") public Object around(ProceedingJoinPoint pdj) { Object result=null; String name=pdj.getSignature().getName(); //执行目标方法 try { //前置通知 System.out.println(name+" begin with " + Arrays.asList(pdj.getArgs())); result = pdj.proceed(); //后置通知 System.out.println(name+" end with " + Arrays.asList(pdj.getArgs())); } catch (Throwable e) { // TODO 自动生成的 catch 块 //异常通知 System.out.println(name+" exception " + e); throw new RuntimeException(e); } //后置通知 System.out.println(name+" end "); return result; } }