ssm框架整合AOP,实现日志记录功能

在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;
	}
}

嗯,就这样,就可以实现一个切面日志功能,我还是希望大家能对刚开始我提的那四点知识,多放在心上,多学习。

©️2020 CSDN 皮肤主题: 游动-白 设计师:上身试试 返回首页