1. 程式人生 > >ssm框架整合AOP,實現日誌記錄功能

ssm框架整合AOP,實現日誌記錄功能

在ssm框架中,實現一個切面日誌功能,起碼要掌握的知識有四點:

以下是自己之前做的一個專案,希望對你們有幫助

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

嗯,就這樣,就可以實現一個切面日誌功能,我還是希望大家能對剛開始我提的那四點知識,多放在心上,多學習。