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

posted @ 2016-08-31 16:37  lichmama  阅读(664)  评论(0编辑  收藏  举报