@RequestMapping(method = RequestMethod.GET)public String showEmployees(Model model) {List<Employee> employees = employeeDao.list();model.addAttribute('employees', employees);return 'employees/list';}
他編寫了以下代碼:
@RequestMapping(method = RequestMethod.GET)public String showEmployees(Model model) {LOGGER.log('Invoking method showEmployees');List<Employee> employees = employeeDao.list();model.addAttribute('employees', employees);LOGGER.log('Returning from method showEmployees');return 'employees/list';}
此代碼有什么問題? 好:
- 用這樣的代碼更改每種方法都需要花費大量時間
- 容易出錯-您可以輸入錯別字或忘記在某處添加日志記錄
- 這是各方面關注的問題 。 這意味著您要在不屬于其的地方添加相同的重復性,樣板代碼和無關的代碼。
例如,showEmployees方法的職責是什么? 它正在調用服務,招募員工并將其建模。 記錄確實不是責任,那么為什么要混合這些顧慮?
如果我提到的工程師了解面向方面的編程,那么他將節省大量時間,并使代碼更好,更易讀。 Spring支持專門針對此類問題的“方面”。 方面使我們可以在一處定義通用功能。 在我們編寫任何代碼之前,需要了解一些術語。 這個術語非常龐大,我將不在這里寫,但如果您希望了解更多信息,我鼓勵您閱讀AOP上Spring的官方參考頁 。 您至少應該了解什么是建議,連接點,切入點,縱橫比和編織。
好吧,讓我們添加Aspect來記錄控制器方法,這正是從一開始就應該做的工程師工作。
我們必須首先在AspectJ庫上將依賴項添加到pom.xml :
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.6.11</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjtools</artifactId><version>1.6.11</version></dependency>
還要檢查您是否依賴于Spring的AOP(但是如果您從一開始就遵循本教程,則已經擁有它):
<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>3.1.0.RELEASE</version></dependency>
現在讓我們編寫Aspect的代碼。 創建包org.timesheet。 方面并添加ControllerLoggingAspect類:
package org.timesheet.aspects;import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut;import java.util.Arrays;/*** Will log every invokation of @RequestMapping annotated methods* in @Controller annotated beans.*/ @Aspect public class ControllerLoggingAspect {@Pointcut('within(@org.springframework.stereotype.Controller *)')public void controller() {}@Pointcut('execution(* *(..))')public void methodPointcut() {}@Pointcut('within(@org.springframework.web.bind.annotation.RequestMapping *)')public void requestMapping() {}@Before('controller() && methodPointcut() && requestMapping()')public void aroundControllerMethod(JoinPoint joinPoint) throws Throwable {System.out.println('Invoked: ' + niceName(joinPoint));}@AfterReturning('controller() && methodPointcut() && requestMapping()')public void afterControllerMethod(JoinPoint joinPoint) {System.out.println('Finished: ' + niceName(joinPoint));}private String niceName(JoinPoint joinPoint) {return joinPoint.getTarget().getClass()+ '#' + joinPoint.getSignature().getName()+ '\n\targs:' + Arrays.toString(joinPoint.getArgs());}}
這段代碼說,控制器方法中的@Before和@AfterReturning我們將記錄有關其調用的信息(名稱和參數)。 當所有三個切入點都匹配時,將執行此建議。 controller()切入點標記了應在其上編織建議的匹配連接點(與構造型Controller匹配)。 methodPointcut()標記我們正在處理方法調用,而requestMapping() 切點標記使用@RequestMapping注釋的方法。
為了使其工作,我們將在src / main / resources下添加aop.xml Spring配置文件:
<?xml version='1.0' encoding='UTF-8'?> <beans xmlns='http://www.springframework.org/schema/beans'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:aop='http://www.springframework.org/schema/aop'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd'><!-- AOP support --><bean id='controllerAspect' class='org.timesheet.aspects.ControllerLoggingAspect' /><aop:aspectj-autoproxy><aop:include name='controllerAspect' /></aop:aspectj-autoproxy></beans>
然后,將其導入timesheet-servlet.xml Spring配置中:
<import resource='classpath:aop.xml' />
這是教程的最后一部分。 我希望您現在對Spring是什么以及它如何幫助解決您的問題有更好的了解。 請記住,在本教程中我們僅涵蓋了Spring的一小部分。 還有更多值得探索的地方!
參考: 第6部分–在vrtoonjava博客上從我們的JCG合作伙伴 Michal Vrtiak 添加AOP支持 。
翻譯自: https://www.javacodegeeks.com/2012/09/spring-adding-aop-support.html