自定义注解(spring)--包含使用AOP创建日志系统

终于有时间可以在这里写一篇博文了,今天写一下我在项目中用到的自定义注解,就是在每次操作项目的时候,想把它的操作加在我的数据库中,简单地说就是日志管理,这些东西都写完之后,我就问我自己,问什么要自定义注解写,而不是什么模式(代理模式,装饰器模式…),原始代码等等,一下子楞了,于是学习了这个东西,今天就在这里总结一下。。。 
编程思想:垂直化编程,就是A—B—C—D…等执行下去,一个逻辑一个逻辑完了再执行下一个,但是spring 中AOP提供了一种思想,它的作用就是,当在业务不知情的情况下,对业务代码的功能的增强,这种思想使用的场景,例如事务提交、方法执行之前的权限检测、日志打印、方法调用事件等等。 
就利用我的日志管理来述说一下这个AOP思想下的自定义注解是如何来实现的。。。 
java在我们要自定义注解的时候提供了它自己的自定义语法以及元注解,元注解(负责注解其他注解): Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它 annotation类型作说明。Java5.0定义的元注解: 
    1.@Target, 
    2.@Retention, 
    3.@Documented, 
    4.@Inherited 
  这些类型和它们所支持的类在java.lang.annotation包中可以找到。 
  1.@Target:用户描述注解的作用范围 
  取值(ElementType)有: 
    1.CONSTRUCTOR:用于描述构造器 
    2.FIELD:用于描述域 
    3.LOCAL_VARIABLE:用于描述局部变量 
    4.METHOD:用于描述方法 
    5.PACKAGE:用于描述包 
    6.PARAMETER:用于描述参数 
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明 
2.@Retention:表示需要在什么级别保存该注释信息 
取值(RetentionPoicy)有: 
    1.SOURCE:在源文件中有效(即源文件保留) 
    2.CLASS:在class文件中有效(即class保留) 
    3.RUNTIME:在运行时有效(即运行时保留)(常用) 
  3.@Documented:Documented是一个标记注解 
  4.@Inherited :用于声明一个注解; 
自定义注解语法: 
public @interface 注解名 {定义体}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

    String value() default "";
}
  

注意: 
1.只能用public或默认(default)这两个访问权修饰.例如,String value();这里把方法设为default默认类型 
2.这里的参数成员可以是八种基本数据类型,和String,Enum,Class,annotations等数据类型,以及这一些类型的数组,这里是String 
3.最好把参数名称设为”value()” 后面为默认的值。

/**
 * 系统日志,切面处理类
 * 
 * @author stm
 * @email [email protected]
 * @date 2017年11月21日
 */
@Aspect
@Component
public class SysLogAspect {

    @Autowired
    private LogService logService;
    //这个里面需要写自定义注解的全限定名(包名+类名)
    @Pointcut("@annotation(com.bw.controller.base.annotation.SysLog)")
    public void logPointCut() { 

    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long beginTime = System.currentTimeMillis();
        //执行方法
        Object result = point.proceed();
        //执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        //保存日志
        saveSysLog(point, time);
        return result;
    }

    /**
     * 保存系统日志
     * @param joinPoint
     * @param time
     */
    private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        /*SysLog syslog = method.getAnnotation(SysLog.class);
        if(syslog != null){
            //注解上的描述
            System.out.println(syslog.value());
        }*/
        /*SysLog sysLog = new ();*/
//获取request请求
        ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = attr.getRequest();

        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
        Browser browser = userAgent.getBrowser();
        String browsers = browser+"";
        System.out.println("浏览器    "+browsers);
        OperatingSystem os = userAgent.getOperatingSystem();
        String oss = os+"";
        System.out.println("os  "+oss);
        String ip = "";
        try {
            ip = InetAddress.getLocalHost().getHostAddress(); //ip 地址
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        System.out.println("ip   "+ip);
        Date date = new Date();
        System.out.println(date);
        com.bw.pojo.system.SysLog  sysLog  =  new com.bw.pojo.system.SysLog();
        SysLog syslog = method.getAnnotation(SysLog.class);
        HttpSession session = request.getSession();
        String userName = (String) session.getAttribute("userName");
        if(syslog != null){
            //注解上的描述
            sysLog.setLogIp(ip);
            sysLog.setLogRemark(syslog.value());
            sysLog.setLogTime(date);
            sysLog.setUserName(userName);
            sysLog.setLogSystem(oss);
            sysLog.setLogBrowser(browsers);
        }
        //请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        //sysLog.setMethod(className + "." + methodName + "()");
        logService.insert(sysLog);
    }
}

如何使用? 
例如在用户登录的时候需要把相关的 信息添加到数据库中,这个时候就需要在登录成功之后在跳转到列表的时候添加注解:

     @SysLog("用户登录")
     @RequestMapping("/main/index")
        public String index(){
            return "main/index";
        }

而这个注解中写的(“用户登录”)就是添加自定义时候的默认值的value()相对应的值。。。 
对了这里需要配置aop以及依赖

<!-- aop 注解实现 -->  
<aop:aspectj-autoproxy/>  
<!-- AspectJ -->  
<dependency>  
    <groupId>org.aspectj</groupId>  
    <artifactId>aspectjrt</artifactId>  
    <version>1.6.10</version>  
</dependency>  
<dependency>  
    <groupId>org.aspectj</groupId>  
    <artifactId>aspectjweaver</artifactId>  
    <version>1.7.2</version>  
</dependency>  

 转载于:https://blog.csdn.net/weixin_38429587/article/details/78807547

猜你喜欢

转载自blog.csdn.net/yinni11/article/details/82019822