spring AOP介绍与使用

来源:互联网 发布:淘宝货退回去了不退钱 编辑:程序博客网 时间:2024/06/05 11:00

1.spring中AOP的“黑话”(名词解释)

名词 解释 Joinpoint(连接点) 可以增强的方法(个人理解就是所有的方法) Pointcut(切入点) 要增强的方法 Advice(通知) 添加的代码(在方法的之前之后加入的代码) Target(目标对象) 被代理的对象 weaving(织入) 将通知应用到连接点的过程 Proxy(代理) 最终形成的代理对象 aspect(切面) 切入点+通知

AOP准备工作

2.导包和加入aop约束

aop+aspects (spring中的包)
aopalliance+aspectj.weaver (额外的包)

2.1准备目标对象

public class UserServiceImpl implements UserService {    public void save() {        System.out.println("保存用户!");        //int i = 1/0;    }    public void delete() {        System.out.println("删除用户!");    }    public void update() {        System.out.println("更新用户!");    }    public void find() {        System.out.println("查找用户!");    }}

2.2准备通知类

public class MyAdvice {    //前置通知  //      |-目标方法运行之前调用    //后置通知(如果出现异常不会调用)//      |-在目标方法运行之后调用    //环绕通知//      |-在目标方法之前和之后都调用    //异常拦截通知//      |-如果出现异常,就会调用    //后置通知(无论是否出现 异常都会调用)//      |-在目标方法运行之后调用//----------------------------------------------------------------    //前置通知    public void before(){        System.out.println("这是前置通知!!");    }    //后置通知    public void after(){        System.out.println("这是后置通知!!");    }    //后置通知    public void afterReturning(){        System.out.println("这是后置通知(如果出现异常不会调用)!!");    }    //环绕通知    public Object around(ProceedingJoinPoint pjp) throws Throwable {        System.out.println("这是环绕通知之前的部分!!");        Object proceed = pjp.proceed();//调用目标方法        System.out.println("这是环绕通知之后的部分!!");        return proceed;    }    //异常通知    public void afterException(){        System.out.println("出事啦!出现异常了!!");    }}

2.3配置目标对象与通知

<!-- 1.配置目标对象 -->    <bean name="userService" class="cn.itcast.service.UserServiceImpl" ></bean><!-- 2.配置通知对象 -->    <bean name="myAdvice" class="cn.itcast.d_springaop.MyAdvice" ></bean>

2.4织入

<!-- 3.配置将通知织入目标对象 -->    <aop:config>        <!-- 配置切入点             public void cn.itcast.service.UserServiceImpl.save()             void cn.itcast.service.UserServiceImpl.save()            * cn.itcast.service.UserServiceImpl.save()            * cn.itcast.service.UserServiceImpl.*()            * cn.itcast.service.*ServiceImpl.*(..)            * cn.itcast.service..*ServiceImpl.*(..)        -->        <aop:pointcut expression="execution(* cn.itcast.service.*ServiceImpl.*(..))" id="pc"/>        <aop:aspect ref="myAdvice" >            <!-- 指定名为before方法作为前置通知 -->            <aop:before method="before" pointcut-ref="pc" />            <!-- 后置 -->            <aop:after method="after" pointcut-ref="pc"/>            <!-- 后置 -->            <aop:after-returning method="afterReturning" pointcut-ref="pc" />            <!-- 环绕通知 -->            <aop:around method="around" pointcut-ref="pc" />            <!-- 异常拦截通知 -->            <aop:after-throwing method="afterException" pointcut-ref="pc"/>        </aop:aspect>    </aop:config>


3.aop注解方式

<!-- 开启使用注解完成织入 -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
//通知类@Aspect//表示该类是一个通知类public class MyAdvice {    @Pointcut("execution(* cn.itcast.service.*ServiceImpl.*(..))")    public void pc(){}    //前置通知    //指定该方法是前置通知,并制定切入点    @Before("MyAdvice.pc()")    public void before(){        System.out.println("这是前置通知!!");    }    //后置通知    @AfterReturning("execution(* cn.itcast.service.*ServiceImpl.*(..))")    public void afterReturning(){        System.out.println("这是后置通知(如果出现异常不会调用)!!");    }    //环绕通知    @Around("execution(* cn.itcast.service.*ServiceImpl.*(..))")    public Object around(ProceedingJoinPoint pjp) throws Throwable {        System.out.println("这是环绕通知之前的部分!!");        Object proceed = pjp.proceed();//调用目标方法        System.out.println("这是环绕通知之后的部分!!");        return proceed;    }    //异常通知    @AfterThrowing("execution(* cn.itcast.service.*ServiceImpl.*(..))")    public void afterException(){        System.out.println("出事啦!出现异常了!!");    }    //后置通知    @After("execution(* cn.itcast.service.*ServiceImpl.*(..))")    public void after(){        System.out.println("这是后置通知(出现异常也会调用)!!");    }}