@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