• Spring AOP应用


    一、Spring AOP框架

      AOP(Aspect Orient Programming),其实也就是面向切面编程。面向对象编程(OOP)是从静态角度考虑程序结构。面向切面编程(AOP)是从动态角度考虑程序运行过程。

      根据个人的理解,AOP执行图大致如下:

    二、Spring AOP相关概念

      1. 切面(Aspect):业务流程运行的某个特定步骤,也就是应用运行过程中的关注点,关注点可以横切多个对象,也称为横切关注点。如示例中的AspectService。

      2. 连接点(Joinpoint):是切面类和业务类的连接点。

      3. 通知(Advice):在切面类中,声明对业务方法执行额外增强处理。

        3.1 前置通知(Before Advice):切入前执行

        3.2 后置通知(After Advice):切入后执行【不管程序在运行过程中是否发生异常】

        3.3 返回后通知(AfterReturning Advice):切入后执行【程序成功运行后】

        3.4 环绕通知(Around Advice):近似等于Before Advice与AfterReturning Advice总和,Around Advice 既可在执行目标方法之前,也可在执行目标方法后,既然如此的不确定为什么不用Before Advice + After Advice代替呢?个人觉得还是省着点用吧

        3.5 异常通知(AfterThrowing Advice):在切入点发生异常时执行    

      4. 切入点(Pointcut):可以插入增强处理的连接点,说白了就是当基本个连接点符合要求时,这个连接点就会添加额外增强处理,这个点也就成了切入点了。

      5. 目标(Target):被代理的对象。

    三、Spring AOP示例【以日志管理为例】

      1. 切面定义

    package com.swyma.spring.service;
    
    import java.util.Date;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Service;
    
    import com.swyma.spring.core.DateUtils;
    
    /**
     * AOP切面
     * @author yemaoan
     *
     */
    @Aspect
    @Service
    public class AspectService {
    
        Log log = LogFactory.getLog(AspectService.class);
        
        @Pointcut("execution(* *.create(..))")
        public void createPointCut() {
            
        }
        
        @Around(value = "createPointCut()")
        public void weaveCreatePointCut(JoinPoint join) {
            Object obj = join.getTarget().getClass().getSimpleName();
            log.info("用户 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 调用了 " + obj + " 并执行了 create 操作");
        }
        
        @Pointcut("execution(* *.modify(..))")
        public void modifyPointCut() {
            
        }
        
        @After(value = "modifyPointCut()")
        public void weaveModifyPointCut(JoinPoint join) {
            log.info("用户 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 执行了 modify 操作");
        }
        
        @Pointcut("execution(* *.delete(..))")
        public void deletePointCut() {
            
        }
    
        @After(value = "deletePointCut()")
        public void weaveDeletePointCut(JoinPoint join) {
            log.info("用户 " + "  " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 执行了 delete 操作");
        }
    }

      2. 目标【target】

        2.1 UserService【用户服务】

    package com.swyma.spring.service;
    
    import org.springframework.stereotype.Service;
    
    import com.swyma.spring.entity.User;
    
    @Service
    public class UserService extends BasicService {
    
        
        public void create(User user) {
            
        }
        
        public void modify(User user) {
            
        }
        
        public void delete(User user) {
            
        }
        
    }

        2.2 RegisteService【注册服务】

    package com.swyma.spring.service;
    
    import org.springframework.stereotype.Service;
    
    @Service
    public class RegisterService extends BasicService {
    
        public void create() {
            
        }
        
    }

      3. 测试类

    package com.swyma.spring.test;
    
    import org.junit.Test;
    
    import com.swyma.spring.core.ISpringContext;
    import com.swyma.spring.entity.User;
    import com.swyma.spring.service.BasicSpringContext;
    import com.swyma.spring.service.LoginService;
    import com.swyma.spring.service.RegisterService;
    import com.swyma.spring.service.UserService;
    
    
    /**
     * JUintTest
     * @author yemaoan
     *
     */
    public class TestSpringEnv {
    
        @Test
        public void testLookup() {
            ISpringContext context = new BasicSpringContext();
            LoginService loginService = context.lookup(LoginService.class);
            loginService.handle();
        }
        
        @Test
        public void testAspect() {
            ISpringContext context = new BasicSpringContext();
            UserService userService = context.lookup(UserService.class);
            RegisterService registerService = context.lookup(RegisterService.class);
            userService.create(new User());
            registerService.create();
        }
        
    }

      4. 运行结果【cosole】

    21:26:30,741  INFO com.swyma.spring.service.AspectService:35 - 用户    在 2013-10-03 21:26:30 调用了 UserService 并执行了 create 操作
    21:26:30,742  INFO com.swyma.spring.service.AspectService:35 - 用户    在 2013-10-03 21:26:30 调用了 RegisterService 并执行了 create 操作

    四、总结

      1. 以上均是个人的对Spring AOP的理解,如有错误之处,望各位网友批评批评,共同探讨,在些先谢过!

      2. Spring AOP核心思想其实是个动态代理的机制,动态代理【DynamicProxy】寻找【JointPoint】连接点,当找到符合要求时就会执行通知【Advice】。

  • 相关阅读:
    1393 0和1相等串 鸽笼原理 || 化简dp公式
    C. Coin Troubles 有依赖的背包 + 完全背包变形
    D. PolandBall and Polygon BIT + 欧拉公式
    51NOD 1639 绑鞋带 数学
    D. Fedor and coupons 二分暴力
    hdu 4104 Discount
    bnu 51640 Training Plan DP
    hdu 5745 La Vie en rose DP + bitset优化
    hdu 5036 Explosion bitset优化floyd
    1354 选数字 DP背包 + 数学剪枝
  • 原文地址:https://www.cnblogs.com/maoan/p/3350572.html
Copyright © 2020-2023  润新知