aop,系统日志,注解

自定义一个注解,稍后aop配置只有加了这个注解的才能被aop扫描到,就是当操作了有自定义注解的方法才会记录到系统日志。

package aop;

import java.lang.annotation.*;

@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
	String title() default "";
	String description()  default "";
}

重点就是切面这个类,正常前置通知,后置返回通知什么的可以获取方法参数,返回值什么的。但是这个是根据有注解才进行切面的,所以也可以获取注解中相应的信息,所以自定义注解要设计好。下面的切面代码是随便写写,真正使用的时候,根据自己的需求修改下就行了。

package aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

@Component
@Aspect
public class HelloAspectJ {

    public HelloAspectJ(){
        System.out.println("HelloAspectJ扫描到了");
    }
  
    @Pointcut(value = "@annotation(aop.SystemControllerLog)")
    public void beforePointcut() {
    }
  
    // 前置通知  
    @Before(value = "beforePointcut()")
    public void beforeHello(JoinPoint joinPoint) throws ClassNotFoundException {
        System.out.println("===========hello beforeHello(前置通知)==" );

        Object obj[] = joinPoint.getArgs();
        for (Object o : obj) {
            System.out.println("目标方法参数值:"+o.toString());
        }

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpSession session = request.getSession();

        String targetName = joinPoint.getTarget().getClass().getName();
        System.out.println("目标方法所在类名称:"+targetName);
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        String methodName = joinPoint.getSignature().getName();
        System.out.println("目标方法名称:"+methodName);
        for (Method method : methods) {
            System.out.println("目标方法所在类的方法:"+method.getName());
            if(method.getName().equals(methodName)) {
                SystemControllerLog annotation = method.getAnnotation(SystemControllerLog.class);
                System.out.println("目标方法注解类标题:"+annotation.title());
                System.out.println("目标方法注解类描述:"+annotation.description());
                Class[] classes = method.getParameterTypes();
                for (Class aClass : classes) {
                    System.out.println("目标方法参数类型:"+aClass.toString());
                }
            }
        }
    }

    // 后置返回通知
    @AfterReturning(value = "execution(* controller..*.*(..))")
    public void afterReturningHello(JoinPoint joinPoint) {
        System.out.println("===========hello afterReturningHello(后置返回通知)==");
    }
}  

在springmvc.xml配置文件中加入包扫描和使用注解方式进行切面

<?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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

    <context:component-scan base-package="controller"/>
    <context:component-scan base-package="aop"/>
    <aop:aspectj-autoproxy/>
    
    ...

</beans>

在controller的方法里加入注解就可以被aop拦截到了,然后就可以在切面的代码里写自己想要的东西了。

package controller;

import aop.SystemControllerLog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloWorldController {
	public HelloWorldController() {
		System.out.println("HelloWorldController扫描到了!!!");
	}

	@RequestMapping("aopTest")
	@SystemControllerLog(title = "hello",description="aopTest")
	public String aopTest(Integer id,String name){
		System.out.println("id:"+id);
		System.out.println("name:"+name);
		return "hello";
	}
}

猜你喜欢

转载自blog.csdn.net/shuair/article/details/81509630