sping aop的自我理解和实现

  AOP  Aspect Oriented Programming 面向切面编程,面向切面编程侧重点在于切面,在程序中寻找共通组件方法,然后将额外功能通过配置切入到组件方法中。

那么在这个过程种只需要搞清楚3个事情

一是切面(指的是在共通位置,加入的共通处理。封装共通处理的组件被称为切面组件)

二是切入点(Spring使用表达式指定切入的目标组件和方法。)其实切入点 就是用代码的形式 找到切面 ,具体的表达式如下

- 方法表达式

            execution(修饰符? 返回类型 方法名(参数列表) throw异常?)

            //匹配load打头方法并返回Object结果
            execution(Object load*(..))
            //匹配DeptController所有方法
            execution(* cn.xdl.DeptController.*(..))
            //匹配cn.xdl下所有类所有方法
            execution(* cn.xdl.*.*(..))


    - 类型表达式

            within(组件类型)
            
            //匹配DeptController所有方法
            within(cn.xdl.DeptController)
            //匹配cn.xdl包下所有类所有方法
            within(cn.xdl.*)
            //匹配cn.xdl包及子包中所有类所有方法
            within(cn.xdl..*)

    - bean名称表达式

            bean(bean的name或id名)

            //匹配id=deptController的组件及方法
            bean(deptController)
            //匹配id名以Controller结尾的组件及方法
            bean(*Controller)

 

三是 通知(啥时候切,指定切入目标方法的时机,例如方法执行前、方法执行后,方法执行前和后、异常发生后等。)

具体如下

<aop:before> 前置通知,在原方法前面切入

    <aop:after-returning> 后置通知,在原方法后面切入(出异常不会执行)

    <aop:after> 最终通知,在原方法执行后切入(有无异常都可以执行)

    <aop:after-throwing> 异常通知,在原方法抛出异常后切入

    <aop:around> 环绕通知,在原方法前面和后面切入

 

那么在知道上述的3个要素以后就可以开始实现了 

eg:记录每个服务调用相关信息,例如服务名、组件名、方法名、调用时间、执行时间(以这个列子来说明)

第一步编写一个切面组件
        public class OperationAspectBean {
            
         
            public Object logOperation(ProceedingJoinPoint pjp) throws Throwable{
                //记录服务调用日志信息
          
                String className = pjp.getTarget().getClass().getName();//组件名
                String methodName = pjp.getSignature().getName();//方法名
                String callTime = new Date().toString();//调用时间
                StopWatch watch = new StopWatch();
                watch.start();//开始计时
                Object obj = pjp.proceed();//执行目标组件方法
                watch.stop();//结束计时
                long executeTime = watch.getTotalTimeMillis();//执行时长
                //打印到控制台或写入数据库
                System.out.println("执行了"+className+"组件的"+methodName
                        +"方法,调用时间为"+callTime+" 执行时长"+executeTime);
                return obj;
            }
            
        }

第二步 把上述的3要素配置进去,并且加入ioc的扫描注入

@Component
        @Aspect
        public class OperationAspectBean {
            
            @Around("within(cn.xdl.controller..*)")
            public Object logOperation(ProceedingJoinPoint pjp) throws Throwable{
                //记录服务调用日志信息
                
                String className = pjp.getTarget().getClass().getName();//组件名
                String methodName = pjp.getSignature().getName();//方法名
            
                String callTime = new Date().toString();//调用时间
                StopWatch watch = new StopWatch();
                watch.start();//开始计时
                Object obj = pjp.proceed();//执行目标组件方法
                watch.stop();//结束计时
                long executeTime = watch.getTotalTimeMillis();//执行时长
                //打印到控制台或写入数据库
                System.out.println("执行了"+className+"组件的"+methodName
                        +"方法,调用时间为"+callTime+" 执行时长"+executeTime);
                return obj;
            }
            
        }

第三步:在xml加入配置

<!-- 开启组件扫描 -->

<context:component-scan base-package="cn.xdl.aspect"/>
<!-- 强制采用cglib技术动态代理 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

哈哈 我只能理解这么多 至于底层 和  Spring AOP原理:动态代理技术。实现分为JDK Proxy动态代理技术(反射)和CGLIB动态代理技术 这句话希望大家给我科普下

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值