aspect 方法入参 获取_自定义注解实现方法入参与出参的日志打印

talk is cheap,show me the code.

代码目录结构:

-src

-main

-java

-resource

-test

-pom

pom.xml

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

4.0.0

com.example

demo

0.0.1-SNAPSHOT

jar

demo

Demo project for Spring Boot

org.springframework.boot

spring-boot-starter-parent

1.5.6.RELEASE

UTF-8

UTF-8

1.8

org.springframework.boot

spring-boot-starter-aop

org.springframework.boot

spring-boot-starter-web

org.springframework.boot

spring-boot-starter-test

test

org.slf4j

slf4j-api

com.alibaba

fastjson

LATEST

org.mockito

mockito-all

LATEST

test

org.powermock

powermock-core

LATEST

test

org.powermock

powermock-api-mockito

LATEST

test

org.powermock

powermock-module-testng

1.7.0

test

org.springframework.boot

spring-boot-maven-plugin

spring-snapshots

Spring Snapshots

https://repo.spring.io/snapshot

true

spring-milestones

Spring Milestones

https://repo.spring.io/milestone

false

spring-snapshots

Spring Snapshots

https://repo.spring.io/snapshot

true

spring-milestones

Spring Milestones

https://repo.spring.io/milestone

false

application.properties 写了,controller 配置了webroot路径和服务器端口。

server.contextPath=/test

server.port=8080

自定义注解类 Log.java:

package com.example.demo.annotation;

import org.springframework.stereotype.Component;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* TYPE -> Class, interface (including annotation type), or enum declaration

* METHOD -> Method declaration

*/

@Target({ElementType.METHOD,ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

public @interface Log {

String value() default "";

boolean ignore() default false;

}

切面类,注解实现->LogAspect.java 。

package com.example.demo.impl;

import com.alibaba.fastjson.JSONObject;

import com.alibaba.fastjson.serializer.SerializerFeature;

import com.example.demo.annotation.Log;

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.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.core.annotation.Order;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**

* Log 注解类实现

*/

@Aspect

@Order(100)

@Component

public class LogAspect {

public static final Logger log = LoggerFactory.getLogger(LogAspect.class);

public static final String dateformat = "yyyy:MM:dd HH:mm:ss";

public static final String STIRNG_START = "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

public static final String STIRNG_END = "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";

//execution the scan of pakage 切点package

@Pointcut("execution( * com.example.demo..*(..))")

public void serviceLog(){

}

@Around("serviceLog()")

public Object around(ProceedingJoinPoint joinPoint) { // ProceedingJoinPoint 为JoinPoint 的子类,在父类基础上多了proceed()方法,用于增强切面

try {

// 获取方法签名

MethodSignature signature = (MethodSignature) joinPoint.getSignature();

//java reflect相关类,通过反射得到注解

Method method = signature.getMethod();

Class> targetClass = method.getDeclaringClass();

StringBuffer classAndMethod = new StringBuffer();

//获取类注解Log

Log classAnnotation = targetClass.getAnnotation(Log.class);

//获取方法注解Log

Log methodAnnotation = method.getAnnotation(Log.class);

//如果类上Log注解不为空,则执行proceed()

if (classAnnotation != null) {

if (classAnnotation.ignore()) {

//proceed() 方法执行切面方法,并返回方法返回值

return joinPoint.proceed();

}

classAndMethod.append(classAnnotation.value()).append("-");

}

//如果方法上Log注解不为空,则执行proceed()

if (methodAnnotation != null) {

if (methodAnnotation.ignore()) {

return joinPoint.proceed();

}

classAndMethod.append(methodAnnotation.value());

}

//拼凑目标类名和参数名

String target = targetClass.getName() + "#" + method.getName();

String params = JSONObject.toJSONStringWithDateFormat(joinPoint.getArgs(), dateformat, SerializerFeature.WriteMapNullValue);

log.info(STIRNG_START + "{} 开始调用--> {} 参数:{}", classAndMethod.toString(), target, params);

long start = System.currentTimeMillis();

//如果类名上和方法上都没有Log注解,则直接执行 proceed()

Object result = joinPoint.proceed();

long timeConsuming = System.currentTimeMillis() - start;

log.info("\n{} 调用结束

return result;

} catch (Throwable throwable) {

log.error(throwable.getMessage(), throwable);

}

return null;

}

}

接口类,测试@Log注解

package com.example.demo.service;

import com.example.demo.AspectBean;

import com.example.demo.annotation.Log;

//@Log(value = "aspect test",ignore = true)

@Log(value = "aspect test",ignore = false)

public interface AspectService {

// @Log("this is a method for test aspect.")

public AspectBean testAspect(AspectBean aspectBean) throws InterruptedException;

public boolean init();

}

接口实现:

package com.example.demo.service;

import com.example.demo.AspectBean;

import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;

import java.util.Date;

@Service("aspectService")

public class AspectServiceImpl implements AspectService {

@Override

public AspectBean testAspect(AspectBean aspectBean) throws InterruptedException {

// sleep 1 second

Thread.sleep(1000);

aspectBean.setName("update name");

aspectBean.setAge(20);

aspectBean.setSex(0);

aspectBean.setBirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));

return aspectBean;

}

@Override

public boolean init() {

return false;

}

}

定义一个bean

package com.example.demo;

public class AspectBean {

private String name;

private int age;

private String birthday;

private int sex;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getBirthday() {

return birthday;

}

public void setBirthday(String birthday) {

this.birthday = birthday;

}

public int getSex() {

return sex;

}

public void setSex(int sex) {

this.sex = sex;

}

@Override

public String toString() {

return "AspectBean{" +

"name='" + name + '\'' +

", age=" + age +

", birthday=" + birthday +

", sex=" + sex +

'}';

}

}

controller:

package com.example.demo.controller;

import com.alibaba.fastjson.JSON;

import com.example.demo.AspectBean;

import com.example.demo.service.AspectService;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;

import java.util.Date;

@RestController

@RequestMapping(value = "/aspect")

public class AspectController {

private static final Logger log = LoggerFactory.getLogger(AspectController.class);

@Autowired

private AspectService aspectService;

@GetMapping(value = "/testaspect")

public String testAspect() throws InterruptedException {

AspectBean aspectBean = new AspectBean();

aspectBean.setAge(18);

aspectBean.setBirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));

aspectBean.setSex(1);

aspectBean.setName("aspect");

return JSON.toJSONString(aspectService.testAspect(aspectBean));

}

@GetMapping(value = "/init")

public boolean init() {

return aspectService.init();

}

}

用的spring boot ,启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class DemoApplication {

public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}

在浏览器上测试:

http://127.0.0.1:8080/test/aspect/testaspect

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 开始调用--> com.example.demo.controller.AspectController#testAspect 参数:[]

2018-02-06 19:26:57.003 INFO 239676 --- [nio-8080-exec-2] com.example.demo.impl.LogAspect :

<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< com.example.demo.service.AspectService#testAspect 参数:[{"age":18,"birthday":"2018-02-06 19:26:56","name":"aspect","sex":1}]

2018-02-06 19:26:58.003 INFO 239676 --- [nio-8080-exec-2] com.example.demo.impl.LogAspect :

aspect test- 调用结束

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

2018-02-06 19:26:58.003 INFO 239676 --- [nio-8080-exec-2] com.example.demo.impl.LogAspect :

调用结束

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

源码稍后上传git.

github地址:

码云地址:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值