springAop整合自定义注解做方法日志配置(源码在附件)

package com.aop.log.anno;

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,ElementType.TYPE})//作用于方法上,类上
public @interface Mylog {

   public String value() default "";//日志信息值

   boolean ingore() default false;//是否忽略

}

package com.aop.log.aspect;

import com.aop.log.anno.Mylog;
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@Aspect
public class LogAspect {

    private Logger logger= Logger.getLogger(LogAspect.class);
    private static final String dateFormat="yyyy-MM-dd HH:mm:ss";

    @Pointcut(value = "execution(* com.aop.log.dao.*.*(..))")
    public void pointCut1(){}

    @Around(value = "LogAspect.pointCut1()")
    public Object aroundLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        //日志信息
        StringBuffer loginfo=new StringBuffer();

        //获得方法签名
        MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
        //获得方法对象
        Method method = methodSignature.getMethod();
        //获得字节码对象
        Class<?> clazz = method.getDeclaringClass();
        //获得类上注解
        Mylog mylog_anno_clazz = clazz.getAnnotation(Mylog.class);
        //获得方法上注解
        Mylog mylog_anno_method = method.getAnnotation(Mylog.class);
        //方法上参数
        Object[] args = proceedingJoinPoint.getArgs();
        //判断类上是否有注解
        if (mylog_anno_clazz!=null){
            if (mylog_anno_clazz.ingore()) {
                //忽略日志 直接执行方法
                return proceedingJoinPoint.proceed(args);
            }
        }
        //判断方法上是否有注解
        if (mylog_anno_method!=null){
                if (mylog_anno_method.ingore()){
                    //忽略日志 直接执行方法
                    return proceedingJoinPoint.proceed(args);
                }
        }

        //拼凑日志信息
        String target=clazz.getName()+"##############"+method.getName();//类名+方法名
        //参数
        StringBuffer params=new StringBuffer();
        if (args.length>0){
            for (Object arg : args) {
                params.append(","+arg.getClass().getName());
            }
            params.substring(1);
        }

        //日志信息
        loginfo.append(target+params);
        //获得起始时间
        SimpleDateFormat sdf=new SimpleDateFormat(dateFormat);
        String start = sdf.format(new Date());

        //日志方法  前置通知
        logger.error("开始调用"+loginfo+"时间:"+start);
        long currentTimeMillis = System.currentTimeMillis();
        //方法执行
        Object proceed = proceedingJoinPoint.proceed(args);
        long currentTimeMillis2 = System.currentTimeMillis();
        //方法耗时
        long wastetime=((currentTimeMillis2-currentTimeMillis)/1000);
        String end = sdf.format(new Date());
        logger.error("方法耗时:"+wastetime+"s"+"时间:"+end);
        return proceed;
    }

}

切面日志环绕通知

package com.aop.log.bean;

public class User {

    private int id;

    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }
}
package com.aop.log.dao;

import com.aop.log.bean.User;

//@Mylog(value = "user dao log",ingore = true)
//@Mylog(value = "user dao log",ingore = false)
public interface UserDao {

    //@Mylog(value = "user dao log",ingore = false)
    //@Mylog(value = "user dao log",ingore = true)
    public void save(User user) throws InterruptedException;

    public void delete();
    public void update();
    public void find();

}
package com.aop.log.dao;

import com.aop.log.bean.User;
import org.springframework.stereotype.Repository;

@Repository("userDaoImpl")
public class UserDaoImpl implements UserDao {
    @Override
    public void save(User user) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(user);
    }

    @Override
    public void delete() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("delete user!!!");
    }

    @Override
    public void update() {
        System.out.println("update user!!!");
    }

    @Override
    public void find() {
        System.out.println("find user!!!");
    }
}
package com.aop.log.test;

import com.aop.log.bean.User;
import com.aop.log.dao.UserDao;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml" )
public class Test {

    @Resource(name = "userDaoImpl")
    private UserDao userDaoImpl;

    @org.junit.Test
    public void test1() {
        User user=new User();
        user.setId(1);
        user.setName("abc");

            //userDaoImpl.save(user);
            userDaoImpl.delete();

    }
}

原文地址:https://www.cnblogs.com/Danial7777777/p/10705230.html

时间: 2024-10-17 14:25:41

springAop整合自定义注解做方法日志配置(源码在附件)的相关文章

spring AOP自定义注解方式实现日志管理

转:spring AOP自定义注解方式实现日志管理 今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在applicationContext-mvc.xml中要添加的 <mvc:annotation-driven />     <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 -->     <conte

spring基于注解和配置源码解读

我们先来建立一个maven项目,引入spring文件,不爱弄的在文章最下面有代码地址可以去下载.先看,后面自己下载代码自己去尝试.先给你们吧,边尝试边看吧. 一.IOC容器注册组件的方式 1. 基础XML注入Bean 是不是超级简单的,我们由浅入深一点点来. 2. 基于注解的方式来配置 我们通过方法名就可以直接得到我们的对象了,默认就是按照方法来装配.也可以通过@Bean(value="newName") 来指定装配的名字. 3. 按照包扫描的方式装配(重点),使用@Component

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析

iOS开发- 自定义遮罩视图(引导, 功能说明)源码+解析 我们平时使用App的时候, 经常在第一次使用的时候, 会有类似"新手教程"之类的东西, 来引导我们应该如何使用这个App. 但是这个"新手教程"不同于常规的引导页(引导页指第一次打开App时候, 弹出的那种介绍视图. 他是静态的, 不需要与用户交互, 可以直接一页页翻, 或者直接跳过.)所谓的"新手教程", 就是按照App的提示, 一步步跟着完成. 那这个"新手教程"

Log4Qt快速入门——Log4Qt日志格式化源码解析

Log4Qt快速入门--Log4Qt日志格式化源码解析 一.Layout 1.Layout简介 Log4Qt提供了多种Layout对象,用于格式化日志输出,指定日志级别.线程名称.Logger名称.日期时间等信息.Layout类是Log4Qt API中的抽象类.PatternLayout:根据一个模式字符串输出日志事件:SimpleLayout:输出日志事件的级别和消息:TTCCLayout:输出日志事件的时间.线程名称.Logger名称和嵌套的诊断上下文信息.PatternLayout和TTC

可自定义的边栏菜单ios源码

这个源码是可自定义的边栏菜单,源码MDMenuViewController,MDMenuViewController提供使用的边栏菜单.菜单项可自定义,由数组组成.菜单上的文字图片等完全支持自定义,菜单还支持横屏. 效果图: <ignore_js_op> 使用方法: 将整个"MDMenuViewController classes"文件夹加入到自己的项目中: 构件各个页面,继承Child类: @interface AboutViewController : MDMenuCh

配置源码管理工具(2)

源码管理是开发中最重要的事情之一,在vs.net里我们通常采用vss进行版本控制,在Eclipse里看帖子说用svn的比例很大,和IDE的集成性也很好. 1:服务器部署 下载地址是:http://subversion.apache.org/packages.html 下载的是CollabNet那个,需要注册,注册很简单. http://www.collab.net/downloads/subversion 安装基本就是按照说明走,没有遇到啥问题,说明书上好像要求是windows 2003 ser

自定义注解实现AOP日志记录

自定义注解 package com.annotation; import java.lang.annotation.*; /** *自定义注解 拦截Controller */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface SystemLog { String module() default ""

[Java]利用拦截器和自定义注解做登录以及权限验证

1.自定义注解 需要验证登录的注解 package com.etaofinance.wap.common; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.Retention

SpringBoot 源码解析 (五)----- Spring Boot的核心能力 - 自动配置源码解析

在上一篇博客中分析了springBoot启动流程,大体的轮廓只是冰山一角.今天就来看一下springBoot的亮点功能:自动化装配功能. 先从@SpringBootApplication开始.在启动流程章节中,我们讲述了SpringBoot2大致的启动步骤,并进行了源码详解.但是在刷新容器这块并未展开,refreshContext(context);简单的一行代码,背后却做了太多事情.所以为了不喧宾夺主,本篇也尽量选取和注解@SpringBootApplication有关的方法讲解. sprin