在ssm框架中,实现一个切面日志功能,起码要掌握的知识有四点:
1:在切面类的方法里面获取一个request
2:springAOP中JoinPoint类的知识
3:用到自定义注解类的知识
4:用到类对象的各种方法
以下是自己之前做的一个项目,希望对你们有帮助
1:先定义一个自定义注解类
@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Operation {
String name();
}
2:然后基于注解,编写一个切面类
/**
* AOP 切面编程,结合日志框架
* @author Administrator
*
*/
@Component
@Aspect
public class BookAOP {
private Logger logger = LoggerFactory.getLogger(BookAOP.class);
@Pointcut("execution(* com.lingshi.bookstore.controller.*.*(..))")
public void method(){
}
@After("method()")
public void after(JoinPoint joinPoint){
System.err.println("this is after.................");
}
@AfterReturning("method()")
public void afterReturning(JoinPoint joinPoint){
// 1:在切面方法里面获取一个request,
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
// 2:通过springAOP切面JoinPoint类对象,获取该类,或者该方法,或者该方法的参数
Class<? extends Object> clazz = joinPoint.getTarget().getClass();
String controllerOperation = clazz.getName();
if(clazz.isAnnotationPresent(Operation.class)){
// 当前controller操作的名称
controllerOperation = clazz.getAnnotation(Operation.class).name();
}
// 获取当前方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// clazz类下的所有方法
Method[] methods = clazz.getDeclaredMethods();
String methodOperation = "";
for (Method m : methods) {
if(m.equals(method)){
methodOperation = m.getName();
if(m.isAnnotationPresent(Operation.class)){
methodOperation = m.getAnnotation(Operation.class).name();
}
}
}
String username = (String) request.getSession().getAttribute("LOGIN_USER");
if(username != null){
logger.info(username + " 执行了 " + controllerOperation + " 下的 " + methodOperation + " 操作! ip地址为"
+ request.getRemoteHost());
}else{
logger.info("未知用户 执行了 " + controllerOperation + " 下的 " + methodOperation + " 操作! ip地址为"
+ request.getRemoteHost());
}
}
}
@Component注解放在类头部,可以实现把这个类,注入到容器中,而不需要再在容器中写配置文件了。
重点注意:因为我是对controller包下的拦截,这个包是配置在springmvc.xml配置文件中的,所以我得把这个切面类,配置到springmvc.xml文件中,而不能配置到spring.xml配置文件。
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.lingshi.bookstore.controller" />
<context:component-scan base-package="com.lingshi.bookstore.aop" />
<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
然后,在controller的类或方法的头部加一个注解:@Operation
如下:
@Operation(name="书籍操作")
@RequestMapping("/easyui")
@Controller
public class EasyUIController {
@Autowired
private BookService bookService;
// @Autowired
// private CategoryService categoryService;
@RequestMapping("/goTo/{path}")
public String goToEasyUI(@PathVariable(value="path") String path){
return path;
}
@Operation(name="查询所有书籍")
@RequestMapping("/findbooks")
@ResponseBody
public String findBooksByEasyUi(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "rows", defaultValue = "10") Integer rows,Book book){
// 1.查询记录总数
Pager<Book> pager = new Pager<Book>(page, rows);
int total = bookService.findByPagerCount(pager);
// 2.执行分页查询
List<Book> books = bookService.findByPager(pager);
// 3.对数据进行封装和转换(成json字符串)
Map<String, Object> result = new HashMap<>();
result.put("total", total);
result.put("rows", books);
String json = new Gson().toJson(result);
//logger.info("喜华》》》查询操作");
// 4.返回json字符串数据给浏览器客户端
return json;
}
}
嗯,就这样,就可以实现一个切面日志功能,我还是希望大家能对刚开始我提的那四点知识,多放在心上,多学习。