@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