SpringAOP使用

使用SpringAOP

AOP是什么?

    Aspect Oriented Programming(面向切面编程):将有共同处理的业务,从传统的业务中抽离出来单独的封装,通过装配(注解)的方式作用于系统。在不修改系统业务逻辑的前提下给系统追加功能。

AOP三要素

1.切面:追加什么?单独封装的切面代码。

2.通知:什么时候追加?前置,后置,异常,最终,环绕。

3.切入点:切谁?方法/类型/bean限定表达式。

通知类型

    Spring提供了五种通知类型:

        1.前置通知@Before):在连接点前执行。

        2.后置通知@AfterReturnning):在连接点后正常返回执行(ps:如果方法抛出异常则不会执行)。

        3.异常通知@AfterThrowing):在连接点抛出异常之后执行。

        4.最终通知@After):在连接点执行完成后执行。不管连接点是正常执行完成还是抛出异常后,都会执 行。

        5.环绕通知@Around:在连接点前后执行,是一个强大的通知类型。可以决定方法是否继续执行。通过调用ProceedingJoinPoint的proceed()。

执行顺序:首先执行的是环绕通知中调用proceed()前的代码,其次调用前置通知,再执行被切方法(ps:如果这时方法抛出异常回去执行异常通知),接着继续执行环绕通知调用proceed()后的代码,然后执行最终通知,最后执行后置通知

切点表达式:

    1.匹配方法签名:execution(修饰词 返回值 方法名(参数) 抛出异常)

    execution(* com.xxx.service.*(..)):匹配指定包中的所有方法。

    execution(public * com.xxx.service.UserService.*(..)):匹配指定类的所有public方法。

    execution(* com.xxx.service.UserService.crtUser(..)):匹配UserService类中的crtUser方法。

    2.匹配类型签名:

    within(com.xxx.service.*):匹配指定包中所有的方法,但不包括子包。

    within(com.xxx.service..*):匹配指定包及其子包中所有方法。

    within(com.xxx.service.UserService):匹配指定类中所有方法。

    within(com.xxx.dao.UserDao+):匹配指定接口所有的实现类中的方法。

    3.匹配Bean名字

    bean(*Service):匹配名字以Service结尾的Bean中的所有方法。

    4.组合使用表达式:

    bean(*Service || *ServiceImpl):匹配以Service或ServiceImpl结尾的bean。

    bean(*Service) && within(com.xxx.service):匹配名字已Service结尾,并且在包com.xxx.service中的bean。

动态代理:

    AOP底层实现是通过动态代理技术来实现的,所谓的动态代理就是动态创建类的技术。动态代理技术有两种:1.基于接口技术,实现接口重写了接口中的方法。2.基于类的技术,继承类后重写类的方法。第一种是java内部的反射机制生成字节码并生成对象来实现的,第二种是使用cglib产生代理,而底层是借助sm来实现的,这个asm就是一个java字节码操纵框架,他能用来动态生成类增强类的功能。(由于我目前对动态代理了解不深就先介绍到这里)

简单实现:

1.在spring配置文件中添加配置如下

<!-- 扫面指定的包让spring管理带有特定注解的对像 -->
<context:component-scan base-package="com.xxx.service"/>
<!-- 启动aop注解 -->
<aop:aspectj-autoproxy />

2.切面类,也就是需要追加的代码以及代码的追加方式

    

package com.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * Created by hang on 2018/3/12.
 */
@Component
@Aspect//表示下面的代码是切面组件
public class AspectDemo {

    @Before("execution(* com.Service.EntryService.addEntry(..))")
    public void testAop(){
        System.out.println("AOP实现注入");
        System.out.println("在执行方法前");
    }
    @AfterReturning("execution(* com.Service.EntryService.addEntry(..))")
    public void testAop2(){
        System.out.println("AOP实现注入");
        System.out.println("在执行方法后");
    }
    @After("execution(* com.Service.EntryService.addEntry(..))")
    public void testAop4(){
        System.out.println("AOP实现注入");
        System.out.println("After执行");
    }
    @Around("execution(* com.Service.EntryService.addEntry(..))")
    public Map<String,String> testAop3(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("AOP实现注入");
        System.out.println("环绕前执行");
        Map map = (Map) pjp.proceed();
        System.out.println("AOP实现注入");
        System.out.println("环绕后执行");
        return map;
    }
}

 

@Service
public class EntryService {

    public void add(){
        System.out.println("UserService add()");
    }

    public boolean delete(){
        System.out.println("UserService delete()");
        return true;
    }

    public void edit(){
        System.out.println("UserService edit()");
        int i = 5/0;
    }


}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值