Spring(2)AOP

  1. 什么是AOP?
    AOP是面向切面编程,采用横向抽取机制,取代传统纵向继承机制,将业务无关的代码解耦,适用于性能监视,操作日志的记录,权限校验等。横向抽取即通过代理向目标方法织入增强方法。

  2. Spring AOP
    Spring中Aop底层基于动态代理实现的。
    目标对象如果有接口,自动使用jdk动态代理。
    如果没有接口,自动使用cglib动态代理。
    (底层自动切换,不需要人为手动修改)

  3. 什么是目标对象?
    (Target)目标对象:要被增强(处理)的方法的对象。企业开发中,一般是以业务层的对象作为目标对象

  4. 怎么找到目标对象需要增强(处理)的方法?
    Joinpoint(连接点)和PointCut(切入点)
    joinpoint:指代需要增强(处理)的目标对象的特定方法(要处理的方法
    PointCut:切入点就是表达式(包名.类名.方法名),用来找到对应的要增强(处理)的目标对象的特定方法(怎么找连接点

  5. 如何对需要增强(处理)的方法进行处理?
    Aspect(切面类)与Advice(通知)
    Aspect(切面类):Advice所在的类,称为切面类
    是切入点和通知的结合
    Advice(通知):增强目标对象特定方法的方法,根据触发位置不同,而分成
    前置通知Before(目标对象特定方法执行之前触发),

    @Before("pointcut()")
        public void before(JoinPoint jp){
    //获得要处理目标对象的方法名以及方法的参数
            System.out.println("前置通知:在目标对象方法执行之前执行:");
            System.out.println("拦截到要处理的方法的名字");
            String name = jp.getSignature().getName();//要处理目标对象的方法的方法名
            System.out.println("方法名:"+name);
            System.out.println("获得目标对象的方法的参数:");
            Object[] args = jp.getArgs();
            for (Object arg : args){
                System.out.println("参数:"+arg);
            }
        }

    后置通知AfterReturning(目标对象特定方法执行结束以后触发,且没有出现异常),
    //后置通知:目标对象方法执行结束以后,执行后置通知(可以获得当前方法的返回值)
        @AfterReturning(value = "pointcut()",returning = "result")
        public void afterReturning(Object result){
            System.out.println("后置通知:获得目标对象方法的返回值");
            System.out.println(result);
        }

    最终通知After,
    //最终通知:最后被执行
        @After("pointcut()")
        public void myAfter(){
            System.out.println("最终被执行!");
        }

    异常通知AfterThrowing(目标对象特定方法出现异常触发),
    异常用的是Exception的父类,Throwable
    //异常通知:只有当目标对象,出现异常,才执行异常通知。反之如果没有异常,不执行通知。
        @AfterThrowing(value = "pointcut()",throwing = "ex")
        public void exception(JoinPoint joinPoint,Throwable ex){
            System.out.println(joinPoint.getSignature()+"方法抛出异常了");
            System.out.println(ex.getMessage());
        }

    环绕通知Around(目标对象特定方法执行前后分别被触发)
    //环绕通知:在目标对象方法执行前后分别执行(调用目标对象方法的时候,执行环绕通知)
        @Around("pointcut()")
        public Object around(ProceedingJoinPoint proceedingJoinPoint)throws java.lang.Throwable{
            System.out.println("环绕通知----------------------目标对象方法执行之前");
    //执行目标对象的方法
            Object result = proceedingJoinPoint.proceed();
            System.out.println("环绕通知----------------------目标对象方法执行之后");
            return result;
        }
    频繁的出现execution(* com.kkb.spring.service.*.*(..))要进行封装
    @Pointcut("execution(* com.kkb.spring.service.*.*(..))")
        private void pointcut(){}
    通过配置文件进行控制
    public void before(JoinPoint jp){
    //获得要处理目标对象的方法名以及方法的参数
            System.out.println("前置通知:在目标对象方法执行之前执行:");
        }
    
        public void afterReturning(Object result){
            System.out.println("后置通知:获得目标对象方法的返回值");
            System.out.println(result);
        }
    
        public void exception(JoinPoint joinPoint,Throwable ex){
            System.out.println(joinPoint.getSignature()+"方法抛出异常了");
            System.out.println(ex.getMessage());
        }
    
        public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
            System.out.println("环绕通知----------------------目标对象方法执行之前");
    //执行目标对象的方法
            Object result = proceedingJoinPoint.proceed();
            System.out.println("环绕通知----------------------目标对象方法执行之后");
            return result;
        }
        public void myAfter(){
            System.out.println("最终被执行!");
        }
     
    <context:component-scan base-package="com.kkb.spring.service com.kkb.spring.aop"></context:component-scan>
        <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
    
        <aop:config>
            <!--切入点:可以考虑给目标对象中任意的一个方法添加一个切入点-->
            <aop:pointcut id="t1" expression="execution(* com.kkb.spring.service.*.insert*(..))"/>
            <aop:pointcut id="t2" expression="execution(* com.kkb.spring.service.*.update*(..))"/>
            <aop:pointcut id="t3" expression="execution(* com.kkb.spring.service.*.delete*(..))"/>
            <aop:pointcut id="t4" expression="execution(* com.kkb.spring.service.*.find*(..))"/>
            <!--切面:切入点和通知结合-->
            <aop:aspect ref="myAspect2">
                <aop:before method="before" pointcut-ref="t1"/>
                <aop:before method="before" pointcut-ref="t4"/>
                <aop:after-returning method="afterReturning" pointcut-ref="t4" returning="result"/>
                <aop:after-throwing method="exception" pointcut-ref="t4" throwing="ex"></aop:after-throwing>
                <aop:around method="around" pointcut-ref="t1"/>
                <aop:after method="myAfter" pointcut-ref="t1"/>
            </aop:aspect>
        </aop:config>

  6. *:0-多个字符
    .. :在方法的形参列表中,表示参数任意。在包名后,表示当前包及其子包
    pointcut表达式格式:
    execution(访问权限 返回值类型 包名.类名.方法名(参数列表) 异常类型)
    execution(* com.jwt.aop.*.*(..))表示aop包下任意类中的任意方法
    execution(* com.jwt..*.*(..))表示jwt包及其子包下任意类中的任意方法
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值