• SpringAOP的运用方式——注解方式和XML配置方式


    SpringAOP的运用方式——注解方式和XML配置方式

    AOP(Aspect Oriented Programming):面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

    主要功能

    日志记录,性能统计,安全控制,事务处理,异常处理等等。

    主要意图

    将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
     
    AOP在运用中,大体可以通过两种处理方式:注解方式XML配置方式
    (一)、注解方式
      a.controller
    package controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping
    public class ProjectController {
        @RequestMapping("/success/{param}")
        public String goContent(@PathVariable String param, Model model){
            System.out.println(param + "调用了 Controller");
            model.addAttribute("userName",param);
            return "/success";
        }
    }
    需要通过AOP自动添加日志的controller
      b.切面处理的逻辑
    package north;
    
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    
    import java.io.IOException;
    
    @Configuration
    @EnableAspectJAutoProxy
    @ComponentScan(basePackages = "controller")
    @Aspect
    public class AspectStyleNorth {
        @Pointcut("execution(* controller.*.*(..))")
        public void pointcut() {
            System.out.println("定义切点.....");
        }
    
        @Before(value="pointcut()")
        public void before() {
            System.out.println("AspectStyleNorth.before()方法执行前执行.....");
        }
    
        @After("pointcut()")
        public void after(JoinPoint joinPoint) throws IOException {
            System.out.println("AspectStyleNorth.after()方法执行后执行.....");
        }
    
        @Around(value="pointcut()")
        public Object around(ProceedingJoinPoint pjp){
            System.out.println("AspectStyleNorth.around()方法环绕start.....");
            Object rs = new Object();
            try {
                rs = pjp.proceed();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            System.out.println("AspectStyleNorth.around()方法环绕end.....");
            return rs;
        }
    
        @AfterThrowing(value="pointcut()", throwing="e")
        public void exception(Exception e) {
            //记录异常
            System.out.println("exception ["+e+"]");
        }
    
    }
    注解AOP处理的编写

      c.springmvc.xml中需要配置对 注解类的扫描

    <context:component-scan base-package="north"></context:component-scan>

      d.效果

    【说明】:around()与before() 开始执行的先后不确定,但before() 必定在around()中 proceedingJoinPoint.proceed()之前执行。

    (二)、XML配置方式
      a.controller
    package controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping
    public class ProjectController {
        @RequestMapping("/success/{param}")
        public String goContent(@PathVariable String param, Model model){
            System.out.println(param + "调用了 Controller");
            model.addAttribute("userName",param);
            return "/success";
        }
    }
    需要通过AOP自动添加日志的controller
      b.springmvc.xml 的配置,添加运用到注解的类(bean)的扫描
        <!-- 扫描下方切面配置的各个切点所在的包 -->
        <context:component-scan base-package="controller"></context:component-scan>
        
        <!-- 切面配置 -->
        <aop:config>
            <aop:pointcut id="pointcut" expression="execution(* controller.*.*(..))"/>
            <aop:aspect ref="aspectStyleSouth">
                <aop:before pointcut-ref="pointcut" method="before"/>
                <aop:after pointcut-ref="pointcut" method="after"/>
                <aop:around pointcut-ref="pointcut" method="around"/>
                <aop:after-throwing pointcut-ref="pointcut" method="exception" throwing="e"/>
            </aop:aspect>
        </aop:config>
    
        <bean id="aspectStyleSouth" class="south.AspectStyleSouth"/>

    【注】:需要同时扫描两个地方的包:①AOP附加处理逻辑所在的包;②运用到 AOP 的业务逻辑所在的包。

      c.切面处理的逻辑
    package south;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    
    import java.io.IOException;
    
    @Aspect
    public class AspectStyleSouth {
    
        public void before() {
            System.out.println("before方法执行前执行.....");
        }
    
        @Pointcut("execution(* server.*.*(..))")
        public void pointcutA() {
            System.out.println("定义切点.....");
        }
    
        @Before(value="pointcutA()")
        public void beforeA() {
            System.out.println("AspectStyleNorth.before()方法执行前执行.....");
        }
    
    
        /**
         *
         * @Title:doAfterInServiceLayer
         * @Description: 方法调用后触发
         *  记录结束时间
         * @author shaojian.yu
         * @date 2014年11月2日 下午4:46:21
         * @param joinPoint
         */
        public void after(JoinPoint joinPoint) throws IOException {
            Object[] args = joinPoint.getArgs() == null ? new String[]{""} : joinPoint.getArgs();
            System.out.println("after方法执行后执行....."+args[0]);
        }
    
        public Object around(ProceedingJoinPoint pjp){
            System.out.println("around方法环绕start.....");
            Object rs = new Object();
            try {
                rs = pjp.proceed();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            System.out.println("around方法环绕end.....");
            return rs;
        }
    
        public void exception(Exception e) {
            //记录异常
            System.out.println("exception ["+e+"]");
        }
    }
    XML配置方式中,对于的AOP需要添加的处理逻辑

      d.效果

    项目的目录:

     

    延伸:

    1.在AOP中,需要用到传参的时,可参考:【第六章】 AOP 之 6.3 基于Schema的AOP ——跟我学spring3

    2.AOP中,方法、路径、参数等匹配的表达式,可参考:Aspectj execution表达式

     
  • 相关阅读:
    bootstrap的demo网站
    百度地图和js操作iframe
    (转)关于List中FindAll用法的一些简单示例
    (转)ORACLE触发器详解
    多线程Java Socket编程示例(转)
    java Socket用法详解(转)
    java socket编程基础(转)
    Java Socket 基础例子
    C# Socket服务器端如何判断客户端断开
    windows server 2008 R2 远程连接用户数修改
  • 原文地址:https://www.cnblogs.com/bridgestone29-08/p/11349536.html
Copyright © 2020-2023  润新知