zoukankan      html  css  js  c++  java
  • SpringMVC利用AOP实现自定义注解记录日志

    https://blog.csdn.net/spring_show/article/details/78049110

    第一,注解:

    @Before – 目标方法执行前执行

    @After – 目标方法执行后执行

    @AfterReturning – 目标方法返回后执行,如果发生异常不执行

    @AfterThrowing – 异常时执行

    @Around – 在执行上面其他操作的同时也执行这个方法

    第二,SpringMVC如果要使用AOP注解,必须将放在spring-servlet.xml(配置MVC的XML)中


    <aop:aspectj-autoproxy proxy-target-class="true"/>
    项目截图

    首先是Maven依赖

    <properties>
            <springframework>4.0.5.RELEASE</springframework>
            <aspectj>1.8.5</aspectj>
            <servlet>3.1.0</servlet>
        </properties>
        <dependencies>
            <!-- servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>${servlet}</version>
                <scope>compile</scope>
            </dependency>
            <!-- Spring web mvc -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${springframework}</version>
            </dependency>
            <!-- Spring AOP -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aop</artifactId>
                <version>${springframework}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>${aspectj}</version>
            </dependency>
        </dependencies>
    spring-context.xml配置,基本无内容

    <!-- 配置扫描路径 -->
        <context:component-scan base-package="org.xdemo.example.springaop">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
        </context:component-scan>
    spring-mvc.xml配置

    <!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 -->
        <aop:aspectj-autoproxy proxy-target-class="true"/>
        <!-- 启用MVC注解 -->
        <mvc:annotation-driven />
     
        <!-- 指定Sping组件扫描的基本包路径 -->
        <context:component-scan base-package="org.xdemo.example.springaop">
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
    Web.xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
        <display-name>Archetype Created Web Application</display-name>
        <!-- WebAppRootKey -->
        <context-param>
            <param-name>webAppRootKey</param-name>
            <param-value>org.xdemo.example.springaop</param-value>
        </context-param>
     
        <!-- Spring Context -->
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-context.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
     
        <!-- SpringMVC -->
        <servlet>
            <servlet-name>SpringMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:spring-mvc.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
     
    </web-app>
    注解Log

    package org.xdemo.example.springaop.annotation;
     
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
     
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD })
    public @interface Log {
        String name() default "";
    }
    日志AOP,写法一LogAop_1

    package org.xdemo.example.springaop.aop;
     
    import java.lang.reflect.Method;
    import java.util.UUID;
     
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    import org.xdemo.example.springaop.annotation.Log;
     
    @Aspect
    @Component
    public class LogAop_1 {
     
        ThreadLocal<Long> time=new ThreadLocal<Long>();
        ThreadLocal<String> tag=new ThreadLocal<String>();
         
        /**
         * 在所有标注@Log的地方切入
         * @param joinPoint
         */
        @Before("@annotation(org.xdemo.example.springaop.annotation.Log)")
        public void beforeExec(JoinPoint joinPoint){
             
            time.set(System.currentTimeMillis());
            tag.set(UUID.randomUUID().toString());
             
            info(joinPoint);
             
            MethodSignature ms=(MethodSignature) joinPoint.getSignature();
            Method method=ms.getMethod();
            System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
        }
         
        @After("@annotation(org.xdemo.example.springaop.annotation.Log)")
        public void afterExec(JoinPoint joinPoint){
            MethodSignature ms=(MethodSignature) joinPoint.getSignature();
            Method method=ms.getMethod();
            System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
        }
         
        @Around("@annotation(org.xdemo.example.springaop.annotation.Log)")
        public void aroundExec(ProceedingJoinPoint pjp) throws Throwable{
            System.out.println("我是Around,来打酱油的");
            pjp.proceed();
        }
         
        private void info(JoinPoint joinPoint){
            System.out.println("--------------------------------------------------");
            System.out.println("King: "+joinPoint.getKind());
            System.out.println("Target: "+joinPoint.getTarget().toString());
            Object[] os=joinPoint.getArgs();
            System.out.println("Args:");
            for(int i=0;i<os.length;i++){
                System.out.println(" ==>参数["+i+"]: "+os[i].toString());
            }
            System.out.println("Signature: "+joinPoint.getSignature());
            System.out.println("SourceLocation: "+joinPoint.getSourceLocation());
            System.out.println("StaticPart: "+joinPoint.getStaticPart());
            System.out.println("--------------------------------------------------");
        }
         
         
    }
    日志AOP,写法二LogAop_2

    package org.xdemo.example.springaop.aop;
     
    import java.lang.reflect.Method;
    import java.util.UUID;
     
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.After;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.springframework.stereotype.Component;
    import org.xdemo.example.springaop.annotation.Log;
     
    @Aspect
    @Component
    public class LogAop_2 {
     
        ThreadLocal<Long> time=new ThreadLocal<Long>();
        ThreadLocal<String> tag=new ThreadLocal<String>();
         
        @Pointcut("@annotation(org.xdemo.example.springaop.annotation.Log)")
        public void log(){
            System.out.println("我是一个切入点");
        }
         
        /**
         * 在所有标注@Log的地方切入
         * @param joinPoint
         */
        @Before("log()")
        public void beforeExec(JoinPoint joinPoint){
             
            time.set(System.currentTimeMillis());
            tag.set(UUID.randomUUID().toString());
             
            info(joinPoint);
             
            MethodSignature ms=(MethodSignature) joinPoint.getSignature();
            Method method=ms.getMethod();
            System.out.println(method.getAnnotation(Log.class).name()+"标记"+tag.get());
        }
         
        @After("log()")
        public void afterExec(JoinPoint joinPoint){
            MethodSignature ms=(MethodSignature) joinPoint.getSignature();
            Method method=ms.getMethod();
            System.out.println("标记为"+tag.get()+"的方法"+method.getName()+"运行消耗"+(System.currentTimeMillis()-time.get())+"ms");
        }
         
        @Around("log()")
        public void aroundExec(ProceedingJoinPoint pjp) throws Throwable{
            System.out.println("我是Around,来打酱油的");
            pjp.proceed();
        }
         
        private void info(JoinPoint joinPoint){
            System.out.println("--------------------------------------------------");
            System.out.println("King: "+joinPoint.getKind());
            System.out.println("Target: "+joinPoint.getTarget().toString());
            Object[] os=joinPoint.getArgs();
            System.out.println("Args:");
            for(int i=0;i<os.length;i++){
                System.out.println(" ==>参数["+i+"]: "+os[i].toString());
            }
            System.out.println("Signature: "+joinPoint.getSignature());
            System.out.println("SourceLocation: "+joinPoint.getSourceLocation());
            System.out.println("StaticPart: "+joinPoint.getStaticPart());
            System.out.println("--------------------------------------------------");
        }
         
    }
    用到的一个用户类User

    package org.xdemo.example.springaop.bean;
     
    public class User {
     
        private String name;
     
        public String getName() {
            return name;
        }
     
        public void setName(String name) {
            this.name = name;
        }
     
    }
    一个测试的Controller

    package org.xdemo.example.springaop.controller;
     
    import javax.annotation.Resource;
     
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.xdemo.example.springaop.annotation.Log;
    import org.xdemo.example.springaop.bean.User;
    import org.xdemo.example.springaop.service.IUserService;
     
     
    @Controller
    @RequestMapping("/aop")
    public class SpringController {
         
        @Resource IUserService userService;
         
        @Log(name="您访问了aop1方法")
        @ResponseBody
        @RequestMapping(value="aop1")
        public String aop1(){
            return "AOP";
        }
         
        @Log(name="您访问了aop2方法")
        @ResponseBody
        @RequestMapping(value="aop2")
        public String aop2(String string) throws InterruptedException{
            Thread.sleep(1000L);
            User user=new User();
            user.setName(string);
            userService.save(user);
            return string;
        }
         
    }
    一个测试的接口实现类(接口类略)

    package org.xdemo.example.springaop.service;
     
    import org.springframework.stereotype.Service;
    import org.xdemo.example.springaop.annotation.Log;
    import org.xdemo.example.springaop.bean.User;
     
    @Service
    public class UserServiceImpl implements IUserService {
     
        @Log(name = "您访问了保存用户信息")
        public void save(User user) {
            System.out.println(user.getName());
        }
     
    }
    ————————————————
    版权声明:本文为CSDN博主「spring_show」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/spring_show/article/details/78049110

  • 相关阅读:
    替换configparser 中指定的值
    configparser 读取与赋值
    接口测试第五步 --》 拼接url
    接口测试第四步 --》 封装excel
    接口测试第三步 --》 封装请求方法
    接口测试第二步 --》 推荐定义一个log 文件
    超级直观理解tcp握手
    crash 潜水
    提高MySQL查询速度
    JSON文件存入MySQL数据库
  • 原文地址:https://www.cnblogs.com/zhoading/p/12205484.html
Copyright © 2011-2022 走看看