zoukankan      html  css  js  c++  java
  • Spring AOP的实现记录操作日志

    适用场景:

      记录接口方法的执行情况,记录相关状态到日志中。

    注解类:LogTag.java

    package com.lichmama.spring.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface LogTag {
        String value() default "";
    }

    @Target (使用)注解的目标类型:

    CONSTRUCTOR        构造方法声明
    FIELD              字段声明(包括枚举常量)
    LOCAL_VARIABLE     局部变量声明
    METHOD             方法声明
    PACKAGE            包声明
    PARAMETER          参数声明
    TYPE               类、接口(包括注释类型)或枚举声明

    @Retention 注解的生命周期(默认CLASS):

    CLASS       编译器将把注释记录在类文件中,但在运行时VM 不需要保留注释。
    RUNTIME      编译器将把注释记录在类文件中,在运行时VM 将保留注释,因此可以反射性地读取。
    SOURCE       编译器要丢弃的注释。

    @Documented 标记生成javadoc

    切面类:ServiceAspect.java

    package com.lichmama.spring.aop;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.JoinPoint;
    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 com.lichmama.spring.annotation.LogTag;
    
    @Aspect
    @Component
    public class ServiceAspect {
    
        private Log log = LogFactory.getLog(getClass());
    
        @Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)")
        private void pointcut() {
        }
    
        @Before("pointcut()")
        public void doBefore(JoinPoint joinPoint) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            String methodName = signature.getMethod().getName();
            String logTag = ((LogTag) signature.getMethod().getAnnotation(LogTag.class)).value();
            log.info("before calling " + methodName + ", value: " + logTag);
        }
    }

    @Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)") 标注一个切入点,执行任意带有LogTag注解的方法触发。

    业务实现:UserServiceImpl.java

    package com.lichmama.spring.service.impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.lichmama.spring.annotation.LogTag;
    import com.lichmama.spring.dao.IUserDAO;
    import com.lichmama.spring.entity.User;
    import com.lichmama.spring.service.IUserService;
    
    @Service
    public class UserServiceImpl implements IUserService {
    
        @Autowired
        private IUserDAO userDAO;
    
        @LogTag
        @Override
        public User getUserById(int id) {
            return userDAO.getUserById(id);
        }
    
        @LogTag
        @Override
        public void saveUser(User user) {
            userDAO.saveUser(user);
        }
    
        @LogTag
        @Override
        public void updateUser(User user) {
            userDAO.updateUser(user);
        }
    
        @LogTag("dangerous operation")
        @Override
        public void deleteUser(int id) {
            userDAO.deleteUser(id);
        }
    }

    spring配置文件:applicationContext.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: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-3.2.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-3.2.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
    
        <context:component-scan base-package="com.lichmama.spring.aop" />
        <context:component-scan base-package="com.lichmama.spring.dao" />
        <context:component-scan base-package="com.lichmama.spring.service" />
    
        <aop:aspectj-autoproxy proxy-target-class="true" />
    </beans>

    写个测试:

    public class TestCase {
        
        private Log log = LogFactory.getLog(getClass());
    
        private ApplicationContext ctx;
        
        @Before
        public void initSpringContext() {
            ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        }
        
        @Test
        public void testAOP() {
            IUserService userService = ctx.getBean(IUserService.class);
            
            userService.saveUser(new User(1, "lichmama"));
            userService.saveUser(new User(2, "james"));
            userService.saveUser(new User(3, "dwyane"));
            
            userService.updateUser(new User(2, "bill"));
            
            User user = userService.getUserById(2);
            log.info(user.toString());
            
            userService.deleteUser(1);
        }
    }

    16:06:22,517 INFO ServiceAspect:29 - before calling saveUser, value:
    16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
    16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
    16:06:22,550 INFO ServiceAspect:29 - before calling updateUser, value:
    16:06:22,551 INFO ServiceAspect:29 - before calling getUserById, value:
    16:06:22,551 INFO TestSpring:35 - id: 2, name: bill
    16:06:22,551 INFO ServiceAspect:29 - before calling deleteUser, value: dangerous operation

  • 相关阅读:
    热更新--动态加载framework
    封装framework注意点
    zip压缩和解压缩
    iOS 网络请求数据缓存
    tomcat服务器访问网址组成
    iOS--支付宝环境集成
    线程10--NSOperation的基本操作
    线程9--NSOperation
    线程8--GCD常见用法
    线程7--GCD的基本使用
  • 原文地址:https://www.cnblogs.com/lichmama/p/5826547.html
Copyright © 2011-2022 走看看