Spring AOP实现简单的日志功能
2018-07-16 本文已影响0人
秃头哥编程
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方法获取数据库所有记录

可以看看控制台的输出

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