Spring–添加AOP支持

我听到了一个有关一位高级(且酬劳颇丰)软件工程师的故事。 他的任务是记录他正在研究的项目中每个控制器中的每个方法。 工程师重写了所有控制器方法,因此使用如下代码:
@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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值