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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode python第三方库检测_VSCode中使用Pylint检查python代码

为什么使用lint在日常开发中&#xff0c;不同开发人员会写下不同风格的代码&#xff0c;导致代码可维护性变差&#xff0c;为了解决风格不一致问题&#xff0c;我们可以制定代码规范&#xff0c;让开发人员都遵守同样的规范编写代码。在开发过程中&#xff0c;部分代码存在质量…

Spring MVC-集成(Integration)-集成LOG4J示例(转载实践)

以下内容翻译自&#xff1a;https://www.tutorialspoint.com/springmvc/springmvc_log4j.htm 说明&#xff1a;示例基于Spring MVC 4.1.6。 以下示例说明如何使用Spring Web MVC框架来触发LOG4J。首先&#xff0c;让我们使用Eclipse IDE&#xff0c;并按照以下步骤使用Spring W…

NUMA架构和Java

是时候部署您的应用程序了&#xff0c;期待着采购最适合负载要求的硬件。 如今&#xff0c;具有40核或80核的包装盒非常普遍。 总体概念是更多的内核&#xff0c;更多的处理能力&#xff0c;更多的吞吐量。 但是我看到了一些相反的结果&#xff0c;表明小型的CPU密集型测试运行…

存储过程常用技巧

我们在进行pl/sql编程时打交道最多的就是存储过程了。存储过程的结构是非常的简单的&#xff0c;我们在这里除了学习存储过程的基本结构外&#xff0c;还会学习编写存储过程时相关的一些实用的知识。如&#xff1a;游标的处理&#xff0c;异常的处理&#xff0c;集合的选择等等…

vue是用a标签打开新页面_vue 在新窗口打开页面并设置不同的背景

开发一个新系统&#xff0c;前端用的vue&#xff0c;vue是单体应用&#xff0c;所有页面都在一个窗口里实现&#xff0c;但项目要求在点button链接后要新打开一个浏览器页面&#xff0c;解决方法如下&#xff1a;1. 给此button设置新事件 click"createdefect"提交缺陷…

卡尔曼滤波的推导

卡尔曼滤波的推导1 最小二乘法在一个线性系统中&#xff0c;若\(x\)为常量&#xff0c;是我们要估计的量&#xff0c;关于\(x\)的观测方程如下&#xff1a; \[ y Hx v \tag{1.1}\] \(H\)是观测矩阵&#xff08;或者说算符&#xff09;&#xff0c;\(v\)是噪音&#xff0c;\(y…

Java注释-保留

考虑一下Java批注&#xff1a; public interface AnAnnotaton {}带有此注释的类&#xff1a; AnAnnotaton class AnAnnotatedClass{}还有一个测试&#xff0c;检查类中是否存在此批注&#xff1a; import static org.hamcrest.MatcherAssert.assertThat; import static org.h…

MYSQL查询选修三门以上课程_SQL高级查询的练习题

Student(S#,Sname,Sage,Ssex) 学生表Course(C#,Cname,T#) 课程表SC(S#,C#,score) 成绩表Teacher(T#,Tname) 教师表问题&#xff1a;1、查询“001”课程比“002”课程成绩高的所有学生的学号&#xff1b;select a.S# from (select s#,score from SC where C#001) a,(select s#,s…

Determing client's IP

AuthorDeterming clients IPАнатоли&23.04.2009 18:39:46Registered userHow to determine clients IP address in THTTPServer.OnClientConnected, THTTPServer.OnClientDisonnected and TRtcFunction.OnExecute events?Danijel Tkalcec [RTC]23.04.2009 19:45:05…

mysql aa复制_MySQL的复制架构与优化

MySQL的复制架构与优化###########原理###########1.主服务器将更新的数据的sql语句(例如&#xff0c;insert&#xff0c;update&#xff0c;delete等)写入到二进制文件中(由log-bin选项开启)。此二进制文件由一个索引文件跟踪维护。2.从服务器连接(使用I/O线程连接)主服务器&a…

如何安装Gradle

Gradle是一个简单而强大的构建工具。 它类似于Ant构建工具。 它可以很好地管理构建&#xff0c;还可以处理构建依赖性。 Gradle最好的部分是它是开源项目。 如果您正在考虑安装并尝试一下&#xff0c;那么您来对地方了。 Gradle的开发周期为4周&#xff0c;因此&#xff0c;每隔…

nmap使用指南

一、目标指定 1.CIDR标志位 192.168.1.0/24 2.指定范围 192.168.1.1-255 192.168.1-255.1&#xff08;任意位置&#xff09;3.IPv6地址只能用规范的IPv6地址或主机名指定。 CIDR 和八位字节范围不支持IPv6&#xff0c;因为它们对于IPv6几乎没什么用。 -iL <文件名> 主机名…

#Pragma Pack(n)与内存分配

#pragma pack(n) 解释一&#xff1a; 每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n)&#xff0c;n1,2,4,8,16来改变这一系数&#xff0c;其中的n就是你要指定的“对齐系数”。 规则&#xff1a; 1、数据成员对齐规…

Java死了还是无敌?

作家艾萨克阿西莫夫&#xff08;Isaac Asimov&#xff09;曾经说过“唯一不变的就是变化”。 这不仅仅是软件行业中的一个短语&#xff0c;这是绝对的事实。 曾经有一天&#xff0c;Corba为王&#xff0c;但Web Services篡夺了它。 即使在Web服务领域&#xff0c;过去也全都是关…

mysql数据库访问问题吗_#MySQL数据库无法远程访问的问题

在 Ubuntu上装了mysql&#xff0c;因为项目的数据库是mysql&#xff0c;将项目放在tomcat里面webapp下面&#xff0c;一直启动不成功。本来一直以为是jdbc驱动问题&#xff0c;后来发现不是。1.cd /etc/mysql 找到my.cnf查找到bind-address&#xff0c;将 bind-address127.0.0.…

SolidEdge如何复制特征 建立类似于UG 块的概念

直接CtrlC和CtrlV可以实现特征的复制粘贴 按N键可以改变特征方向 已经复制完成的特征要进行定位&#xff0c;则右击该特征&#xff0c;编辑轮廓&#xff0c;可以进行聪慧尺寸的标注 使用特征库的方式&#xff0c;就像UG的块一样&#xff0c;可以给所有零件调用。在任意位置新建…

Gradle自定义插件

本教程介绍了创建Gradle独立自定义插件的方法。 它涵盖以下主题 创建任务&#xff0c;并在“自定义”插件中使用它 独立的自定义插件 简短的插件ID 使用settings.gradle自定义Gradle设置 项目信息&#xff1a; 摇篮版本&#xff1a;1.1 操作系统平台&#xff1a;Ubuntu 1…

mysql映射文件_Mybatis SQL映射文件

简单查询insert添加insert可以使用数据库支持的自动生成主键策略&#xff0c;设置useGeneratedKeys”true”&#xff0c;然后把keyProperty 设成对应的列&#xff0c;就搞定了。比如说上面的StudentEntity 使用auto-generated 为id 列生成主键.还可以使用selectKey元素。下面例…

监听微信、支付宝等移动app及浏览器的返回、后退、上一页按钮的事件方法

在实际的应用中&#xff0c;我们常常需要实现在移动app和浏览器中点击返回、后退、上一页等按钮实现自己的关闭页面、调整到指定页面或执行一些其它操作的 需求&#xff0c;那在代码中怎样监听当点击微信、支付宝、百度糯米、百度钱包等app的返回按钮或者浏览器的上一页或后退按…

第七天作业

---恢复内容开始--- 作业一&#xff1a;nginx服务 二进制安装nginx包 作为web服务修改配置文件 让配置生效&#xff0c;验证配置 直至出现epel的两个文件&#xff0c;否则reinstall, 接下来写配置文件&#xff0c; 这款软件的服务目录&#xff0c; 在里面编辑一些东西&#xff…