通过日志记录对某一页的访问。
有2个控制器和2个简单的jsp页面。
/**
* Copyright 2013 Marin Solutions
*/
package com.captaindebug.audit.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.captaindebug.audit.aspectj.Audit;
/**
* Help Controller, displays some help...
*
* @author Roger
*
*/
@Controller()
public class HelpController {
@Audit("Help") // User has visited the help page
@RequestMapping(value = "/help", method = RequestMethod.GET)
public String showHelp(@RequestParam int pageId, Model model) {
String help = getHelpPage(pageId);
model.addAttribute("helpText", help);
return "help";
}
private String getHelpPage(int pageId) {
return "This is the help text - The Beetles are in Stereo";
}
}
@Audit注释的定义
/**
* Copyright 2013 Marin Solutions
*/
package com.captaindebug.audit.aspectj;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation which indicates that a controller needs auditing
*
* @author Roger
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
String value();
}
这个注释必须有一个值,该值就是用户当前访问的页面的文件名。
/**
* Copyright 2013 Marin Solutions
*/
package com.captaindebug.audit.aspectj;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.beans.factory.annotation.Autowired;
import com.captaindebug.audit.service.AuditService;
/**
* @author Roger
*
*/
@Aspect
public class AuditAdvice {
@Autowired
private AuditService auditService;
/**
* Advice for auditing a user's visit to a page. The rule is that the Before annotation
* applies to any method in any class in the com.captaindebug.audit.controller package
* where the class name ends in 'Controller' and the method is annotated by @Audit.
*
* @param auditAnnotation
* Audit annotation holds the name of the screen we're auditing.
*/
@Before("execution(public String com.captaindebug.audit.controller.*Controller.*(..)) && @annotation(auditAnnotation) ")
public void auditScreen(Audit auditAnnotation) {
auditService.audit(auditAnnotation.value());
}
}
上面这个类用AspectJ的两个注释做了修饰:@Aspect和@Before.@Aspect标明AuditAdvice类是是一个切面,而@Before意味着auditScreen()方法先于任何方法调用,只要这些方法的定义匹配@Before注释参数的表达式。
/**
* Copyright 2013 Marin Solutions
*/
package com.captaindebug.audit.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* A Dummy audit service
*
* @author Roger
*
*/
@Service
public class AuditService {
private static Logger logger = LoggerFactory.getLogger(AuditService.class);
/**
* Audit this screen against the current user name
*
* It's more useful to put this info into a database so that that you can count visits to
* pages and figure out how often they're used. That way, you can focus your design on the
* popular parts of your application. The logger is just for demo purposes.
*/
public void audit(String screenName) {
String userName = getCurrentUser();
logger.info("Audit: {} - {}", userName, screenName);
}
/**
* Get the current logged on user name by whatever mechanism available
*/
private String getCurrentUser() {
return "Fred";
}
}
对于AOP应用,在配置文件中要加上这一句:
<aop:aspectj-autoproxy/>
context:component-scan要这样写:
<context:component-scan base-package="com.captaindebug.audit">
<context:include-filter type="aspectj"
expression="com.captaindebug.audit.aspectj.AuditAdvice" />
</context:component-scan>
程序输出:
INFO : com.captaindebug.audit.controller.HomeController - Welcome home! the client locale is zh_CN
INFO : com.captaindebug.audit.service.AuditService - Audit: Fred - Help
原文:http://www.javacodegeeks.com/2013/07/auditing-a-spring-mvc-webapp-with-aspectj-part-2.html
源代码:http://pan.baidu.com/share/link?shareid=147697170&uk=3878681452