今天想經過AOP的方式定義一個切面進行日誌管理,稍微描述一下html
記錄日誌的類spring
@Component @Aspect public class MyLog { @Around("execution(* cn.edu.ntu.controller.*.*(..)) && @annotation(cn.edu.ntu.interfaces.Log)") public Object around(ProceedingJoinPoint point){ Object result = null; try { long start = System.currentTimeMillis(); result = point.proceed(); System.out.format("打印日誌"); } catch (Throwable e) { e.printStackTrace(); } return result; } }
控制層須要添加日誌的方法數據庫
@Controller @RequestMapping("/user") public class UserController extends BaseController { @Autowired private UserService userService; @RequestMapping("/queryUserList") @Log(module="用戶管理", operation="用戶列表查詢") public String queryUserList(Model model){ User user = null; user = (User) memcacheClient.get("user"); if(user == null){ System.out.println("===從數據庫獲取數據。。。==="); user = userService.queryUserById(1L); memcacheClient.set("user", 60000, user); } System.out.println("userid : " + user.getUserId() + "userName : "+user.getUserName()); model.addAttribute("user", user); return "/userList"; } @RequestMapping("/insertUser") public void insertUser(){ userService.insertUser(new User("wpfc")); } }
自定義日誌註解express
@Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Log { /** * 模塊名稱 */ public String module() default ""; /** * 操做說明 */ public String operation() default ""; }
自動爲spring容器中那些配置@aspectJ切面的bean建立代理,織入切面。mvc
<aop:aspectj-autoproxy proxy-target-class="true"/>
可是一直沒法實現功能,看了這邊文章才恍然大悟 Spring aop @aspect沒法執行切入方法app
因而將aop切面配置(<aop:aspectj-autoproxy proxy-target-class="true"/>)從spring的配置文件挪到了springmvc的配置文件中, 這下才解決了問題。.net
最重要的一點在於(22樓的觀點:若是要是切面切在Service層或是Dao層, 那麼<aop:aspectj-autoproxy proxy-target-class="true"/>放在application.xml也是能夠,主要看你的切面切在了controller層仍是controller之後的層)代理
這才讓我恍然大悟: 我在配置文件中讓springmvc專門管理Controller層,而spring去管理其餘的 (springmvc是處理映射請求,而spring是bean容器)日誌
/*springmvc的配置*/ <!-- 掃描controller springmvc只掃描controller--> <context:component-scan base-package="cn.edu.ntu"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" /> </context:component-scan> /*spring的配置*/ <!-- springmvc controller加上事務無效 http://blog.csdn.net/u011580177/article/details/46840033 Controller層只支持 @Transactional 註解式事務! springmvc.xml只掃描Controller --> <context:component-scan base-package="cn.edu.ntu" annotation-config="true"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" /> </context:component-scan>
個人日誌記錄是放在Controller層,屬於springmvc管理的子容器中,而aspect處在 spring管理的父容器中,所以找不到子容器中的元素,致使日誌記錄不生效(事務不生效童一樣的道理)。code
參考: