Loading

Spring AOP实现简单的日志功能

AOP对代码的侵入性非常的小,是一种可插拔的思想,大大降低了耦合度,AOP在许多地方都有应用,这篇文章就看看使用AOP实现日志的功能,也算是AOP思想的一种体现了。

主要是在用户访问一个URL前,记录用户的ip,访问方式,访问的URL,访问的哪个方法以及该方法的参数,访问URL后,记录访问返回的结果。

整个项目基于Spring Boot构建。

#####首先建立一个实体类Man,对应数据库中的一个表

@Entity
public class Man {
	// 主键、自增
	@Id
	@GeneratedValue
	private Integer id;
	private String name;
	private Integer age;
    // 省略get/set方法
}

#####使用jpa实现基本的CRUD(没搞service,直接在controller里干了,凑合着看~)

@RestController
@RequestMapping("/man")
public class ManController {
	@Autowired
	private ManDao manDao;
	
	@Autowired
	private ManService manService;
	
	private Logger logger = LoggerFactory.getLogger(ManController.class);
	
	/**
	 * 添加一条记录
	 * @param man 结果集合
	 * @Validated 注解
	 * @return
	 */
	@GetMapping("/insertMan")
	public Man insertOne(@Validated Man man, BindingResult br) {
		man.setName(man.getName());
		man.setAge(man.getAge());
		return manDao.save(man);
	}
	
	/**
	 * 获取所有记录
	 * @return
	 */
	@GetMapping("/manList")
	public List<Man> getList() {
		logger.info("getList");
		return manDao.findAll();
	}
	
	/**
	 * 根据id查询一条记录
	 * @param id
	 * @return
	 */
	@GetMapping("/man/{id}")
	public Man getOne(@PathVariable("id") Integer id) {
		return manDao.findOne(id);
	}
	
	/**
	 * 更新指定的一条记录
	 * @param id
	 * @param name
	 * @param age
	 * @return
	 */
	@GetMapping("/updateMan/{id}")
	public Man updateOne(@PathVariable("id") Integer id, @RequestParam("name") String name, 
			@RequestParam("age") Integer age) {
		Man man = new Man();
		man.setId(id);
		man.setName(name);
		man.setAge(age);
		return manDao.save(man);
	}
	
	@RequestMapping("/deleteMan/{id}")
	public void deleteOne(@PathVariable("id") Integer id) {
		manDao.delete(id);
	}
	
	@RequestMapping("/insertTwo")
	public void insertTwo() {
		manService.insertTwo();
	}
}

#####使用AOP实现日志功能

/**
 * @Component 该注解表示把类加入spring容器
 * @Aspect 该注解表示切面
 * @author liu
 */
@Component
@Aspect
public class Log {
	
	private Logger logger = LoggerFactory.getLogger(Log.class);
	
	/**
	 * 定义一个公共切点,代码复用
	 * 拦截com.codeliu.controller.ManController类下面的所有public方法
	 */
	@Pointcut(value = "execution(public * com.codeliu.controller.ManController.*(..))")
	private void log() {}
	
	/**
	 * 方法执行前切入
	 */
	@Before(value = "log()")
	public void before(JoinPoint joinPoint) {
		ServletRequestAttributes sa = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = sa.getRequest();
		// 获取用户访问的url
		logger.info("url={}", request.getRequestURL());
		// 获取用户访问的方式,get/post
		logger.info("method={}", request.getMethod());
		// 获取的ip
		logger.info("ip={}", request.getRemoteAddr());
		// 获取用户访问的是哪个方法
		logger.info("class_method={}", joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
		// 获取方法的参数
		logger.info("args={}", joinPoint.getArgs());
	}
	
	@After(value = "log()")
	public void after() {
		logger.info("记录操作后");
	}
	
	/**
	 * 打印返回的内容
	 * @param object
	 */
	@AfterReturning(value = "log()", returning = "object")
	public void afterReturn(Object object) {
		logger.info("object={}", object);
	}
}

切点是ManController 下面的所有public方法,在执行方法前,记录访问的URL等信息,方法返回后,记录返回的结果(@AfterReturning注解的returning 属性)。

试着访问一下getList方法获取数据库所有记录
12.png

可以看看控制台的输出
13.png

这样使用aop就实现了一个简单的日志功能。

posted @ 2018-07-15 20:26  CodeTiger  阅读(52)  评论(0编辑  收藏  举报