zoukankan      html  css  js  c++  java
  • Spring AOP功能

        Spring核心思想之一是AOP(Aspect Oriented Programming),即面向切面编程的技术。 AOP让开发人员专注核心业务,而通用逻辑则由专人使用 AOP 技术进行横向切入处理,使得任务分离,提高开发和调试的效率,应用于权限管理、日志管理等。

       假设项目已完成Spring、SpringMVC配置,添加AOP应用

    1.applicationContext.xml开启支持AspectJ注解 

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:p="http://www.springframework.org/schema/p"
    	xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:task="http://www.springframework.org/schema/task"
    	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
    		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd
    		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    	<!-- 自动扫描与装配bean -->
    	<context:component-scan base-package="com.product"></context:component-scan> 
        <!-- 启动对@AspectJ注解的支持 -->
        <aop:aspectj-autoproxy/>
        <aop:aspectj-autoproxy proxy-target-class="true" /> 
    </beans>
    

    2.编写日志切面实现

       2.1 定义日志注解类

    @Inherited
    @Target({ElementType.TYPE, ElementType.METHOD})    
    @Retention(RetentionPolicy.RUNTIME)
    public @interface AppLog {
        String value() default "";
    }
    

     2.2 日志功能

    package com.product.aop;
    
    import java.util.Arrays;
    
    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.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    
    /**
     * 日志demo
     *  
     *
     */
    @Component
    @Aspect
    public class LogAspect {
    
    	private static final Log logger = LogFactory.getLog(LogAspect.class);
    
    	//抽取公共的切入点表达式
    	@Pointcut("@annotation(com.product.aop.AppLog)")
    	public void pointCut() {
    	};
    
    	//在目标方法之前切入
    	@Before("pointCut()")
    	public void logStart(JoinPoint joinPoint) {
    		Object[] args = joinPoint.getArgs();
    		System.out.println("" + joinPoint.getSignature().getName() + "运行以前:参数列表是:{" + Arrays.asList(args) + "}");
    	}
    
    	@After("com.product.aop.LogAspect.pointCut()")
    	public void logEnd(JoinPoint joinPoint) {
    		System.out.println("" + joinPoint.getSignature().getName() + "运行结束。");
    	}
    
    	// JoinPoint在参数表的第一位
    	@AfterReturning(value = "pointCut()", returning = "result")
    	public void logReturn(JoinPoint joinPoint, Object result) {
    		System.out.println("" + joinPoint.getSignature().getName() + "返回运行结果:{" + result + "}");
    	}
    
    	@AfterThrowing(value = "pointCut()", throwing = "exception")
    	public void logException(JoinPoint joinPoint, Exception exception) {
    		System.out.println("" + joinPoint.getSignature().getName() + "异常,信息:{" + exception + "}");
    	}
    
    }
    

    3.业务功能引入切面

    import org.springframework.stereotype.Service;
    
    import com.product.aop.AppLog;
    
    @Service("userService")
    public class UserService {
    
    	/**
    	 * 标记日志注解 
    	 */
    	@AppLog
    	public boolean exists(String userid,String name){
    		System.out.println("getUser");
    		return true;
    	}
    }
    

      

    4.测试

       浏览器请求http://127.0.0.1:8080/aop/user/submit.do?userid=001&name=lilei

       控制台输出结果:

       exists运行以前:参数列表是:{[001, lilei]}
          getUser
       exists运行结束。
       exists返回运行结果:{true}

  • 相关阅读:
    设备管理器里“SM总线控制器”、“其它PCI桥设备”驱动有问题
    MapReduce实现两表的Join--原理及python和java代码实现
    Calendar类经常用法 日期间的转换 set方法有巨坑
    Java 装饰模式(4.4)
    LoadRunner访问Mysql数据库(转)
    linux下定时执行任务的方法
    docker 常用命令
    Docker exec与Docker attach
    docker容器跨服务器的迁移方式export和save(转)
    cpu时间 / cpu利用率计算
  • 原文地址:https://www.cnblogs.com/walkwithmonth/p/12901283.html
Copyright © 2011-2022 走看看