使用AspectJ和Spring简化了AOP

我最近开始研究面向方面的编程(AOP),至少可以说使我兴奋。 当然我很熟悉它,因为我看到它在Spring中用于事务管理,但是我从未深入研究它。 在本文中,我想展示通过AspectJ可以快速掌握AOP和Spring。 本文中的材料基于Ramnivas Laddad出色的AOP书《 AspectJ in Action》 。

AOP不是一种语言,而是一种软件工程方法。 像任何方法一样,它具有不同的实现,并且AspectJ当前是最丰富,最完整的。 由于AspectJ和AspectWerkz合并,现在可以使用注释创建方面。

开发人员编写代码的原因是为了提供某种功能。 对于这种讨论,功能性的种类并不重要:有些人可能想提供业务功能,另一些人可能出于研究目的编写代码,而另一些人则纯粹出于乐趣。 关键是任何信息系统都有其核心动机,即它想要提供的关键功能。 例如,我最近编写了PODAM ,这是一个测试工具,其最终目标是自动填充POJO / JavaBean属性。

每个信息系统也需要正交服务(AOP称之为横切关注点); 例如日志记录,安全性,审核,异常管理等。 尽管信息系统可以分为不同的功能(AOP定义了连接点),但全面需要正交服务。 例如,如果要记录每个公共方法执行所花的时间,则每个公共方法应具有以下伪代码:

public void someBusinessMethod() {long start = System.currentTimeInMilliseconds();doTheBusinessFunctionality();long end = System.currentTimeInMilliseconds();log.debug("The execution of someBusinessMethod took " + (end - start) + " milliseconds");}

在上述方法中,核心功能仅由someBusinessMethod()标识,而其他所有功能仅是记录活动。 最好有以下内容:

//Some external magic happens before the invocation of this method to take the start time
public void someBusinessMethod() {doTheBusinessFunctionality(); }
//Some external magic happens after the invocation of this method to take the end time and logs how long the execution took.

开发人员通常需要整个应用程序中的日志记录,安全性等,而不是单一方法。 AOP允许开发人员通过在外部某个地方(称为“方面”)定义行为以应用于匹配某种模式的所有代码(AOP实际上允许更广泛的功能集,例如添加接口,实例变量,方法,等等,只举一个例子)。 然后,通过AOP所谓的Weaver,将这种授权的行为添加到最终执行代码中。

可以通过多种方式实现:编织可以在源级别,二进制级别和加载时间进行。 您可以将编织器视为C和C ++中的链接器。 源和库链接在一起以创建可执行文件; 编织者将Java代码和方面结合在一起,以创建授权的行为。

Spring通过围绕必须丰富其行为的代码创建一个AOP代理来实现这种授权行为。 以下代码显示了一个基于AspectJ的非常简单的示例; 该示例围绕使用某些身份验证服务执行简单方法。

身份验证服务看起来非常简单(关键不是功能的实现方式,而是可用的身份验证服务):

/*** */
package uk.co.jemos.aop;/*** A simple authenticator service.* * @author mtedone* */
public class Authenticator {public void authenticate() {System.out.println("Authenticated");}}Now let's have a look at the business logic:/*** */
package uk.co.jemos.aop;/*** A simple service which delivers messages* @author mtedone* */
public class MessageCommunicator {public void deliver(String message) {System.out.println(message);}public void deliver(String person, String message) {System.out.println(person + ", " + message);}}

我们希望在调用MessageCommunicator的任何业务方法之前先调用Authenticator。 使用AspectJ注释语法,我们用纯Java编写Aspect:

package uk.co.jemos.aop;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;@Aspect
public class SecurityAspect {    private Authenticator authenticator = new Authenticator();@Pointcut("execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))")public void secureAccess() {};@Before("secureAccess()")public void secure() {System.out.println("Checking and authenticating user...");authenticator.authenticate();}}

上面的代码更加有趣。 一个方面用@Aspect注释标记。 切入点是我们代码中的一个关注点,我们希望我们的Aspect可以加入其中。语法

@Pointcut(“ execution(* uk.co.jemos.aop.MessageCommunicator.deliver(..))”)public void secureAccess(){};

意思是:“定义一个名为secureAccess的切入点,该切入点适用于MessageCommunicator类中的所有传递方法,而不管该方法的返回类型如何”。 接下来的内容被称为建议,这是AOP增强班级行为的地方:

@Before("secureAccess()")
public void secure() {System.out.println("Checking and authenticating user...");authenticator.authenticate();}

上面的代码说:“在对secureAccess()切入点进行任何匹配之前,将代码应用到块中”。 以上所有内容都是纯Java,尽管注释属于AspectJ运行时。 为了在Spring中使用上述方面,我定义了一个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-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"><aop:aspectj-autoproxy /><bean id="messageCommunicator" /><bean id="securityAspect" /></beans>

XML元素:<aop:aspectj-autoproxy />指示Spring围绕各个方面创建代理。 现在,当我从客户端使用MessageCommunicator时:

/**
* @param args
*/
public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:aop-appContext.xml");MessageCommunicator communicator = ctx.getBean("messageCommunicator",MessageCommunicator.class);communicator.deliver("Hello World");communicator.deliver("Marco", "Hello World");
}

我得到以下输出:

信息:从类路径资源[aop-appContext.xml]加载XML bean定义2011年5月15日11:51:41
org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO:在org.springframework.beans.factory.support.DefaultListableBeanFactory@21b64e6a中预先实例化单例:定义bean [org.springframework.aop.config.internalAutoProxyCreator,messageCommunicator,securityAspect]; 工厂层次结构的根检查和认证用户…认证的Hello World 正在检查和认证用户…已认证Marco,Hello World

通过允许我们将外部组件中的横切关注点外部化,然后在需要时将其编织到我们的代码中,AOP大大改变了我们思考软件工程的方式,这允许编写更简洁,更可维护的代码,并且实现不受限制。 另外,如果我们通过使它们可重用而谨慎地编写我们的方面,我们可以快速地建立一个通用,可重用方面的库,以注入的方式为我们的代码添加功能。

采用AOP显然存在弊端,主要是开发人员熟悉该技术所需的学习曲线。 如上面的示例所示,AspectJ定义了自己的语言和语法); @Before注释只是一种可能性:建议可以在对象之前,之后,周围使用; 此外,定义切入点的语法不是Java,而是类似脚本的语法。 AspectJ方面还具有关键字和本机对象,以捕获他们建议的连接点的上下文,并且需要学习此语法。 但是,通过学习这项新颖而令人兴奋的技术所需的额外努力,潜在的收益将大大增加。

参考: Marco Tedone博客中的 JCG合作伙伴 Marco Tedone 使用AspectJ和Spring简化了AOP 。


翻译自: https://www.javacodegeeks.com/2012/04/aop-made-easy-with-aspectj-and-spring.html

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

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

相关文章

第一冲刺阶段 工作总结 04

1、昨天我继续我的任务&#xff0c;连接数据库。 2、今天打算继续做数据库的连接。 3、遇到的问题&#xff1a;昨天在数据库连接时&#xff0c;老是连接不上&#xff0c;显示错误&#xff0c;所以今天打算接着弄。转载于:https://www.cnblogs.com/zz0906/p/5422510.html

windows2012同步linux时间,Windows server2012时间同步NTP配置

遇到经常服务器时间无法同步&#xff0c;可以自己建立一台时间同步服务器&#xff0c;NTP配置如下&#xff1a;一、服务端配置 (Ntp服务器&#xff0c;客户端将根据这台服务器的时间进行同步)1、微软键R键&#xff0c;进入“运行”&#xff0c;输入“regedit”,进入注册表2、 H…

反差萌

反差萌 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 0 Accepted Submission(s): 0 Problem Description有2N个人&#xff0c;每人有个萌值Mi(1<i<2N)。 要求将他们分为N对&#xff0c;使得反差值之和…

Java EE 6示例– Galleria第2部分

您可能在最后一篇Java EE 6 Galleria示例帖子中关注了我。 第一个是基本介绍。 第二个是关于在最新的GlassFish上运行它。 有人提到RedHat&#xff0c;我们应该研究将这个示例从GlassFish中移除。 很好;&#xff09;感谢您的好主意。 这正是我们今天要做的。 我将把Galleria示例…

suggest

http://lovebeyond.iteye.com/blog/941633转载于:https://www.cnblogs.com/sunxun/p/5421251.html

linux的tar命令压缩26g文件,linux如何使用tar命令大包压缩进文件

linux如何使用tar命令大包压缩进文件发布时间&#xff1a;2020-05-29 12:30:14来源&#xff1a;亿速云阅读&#xff1a;206作者&#xff1a;Leah本篇文章主要介绍linux中使用tar命令大包压缩进文件的方法。内容比较详细&#xff0c;文章包含了命令的使用示例&#xff0c;希望大…

与reCAPTCHA的Spring集成

有时我们只需要CAPTCHA &#xff0c;这是一个可悲的事实。 今天&#xff0c;我们将学习如何与reCAPTCHA集成。 因为主题本身并不是特别有趣和高级&#xff0c;所以我们将通过使用Spring Integration处理低级细节来过度设计&#xff08;&#xff1f;&#xff09;。 Google决定使…

《机器学习基石》---感知机算法

1 推导感知机模型 基本思想是&#xff0c;把特征的线性加权值作为一个分数&#xff0c;根据这个分数与一个门限值的关系来进行分类&#xff1a; 我们加一个特征x0等于1&#xff0c;门限值就可以放到w里面去&#xff0c;得到更简单的形式&#xff1a; 这就是感知机模型&#xff…

未知错误:1000正在终止线程

若在try{} catch{}的catch 块中加入 catch (Exception ex) { Response.Write(ex.Message); Response.End(); } 则捕获异常后&#xff0c;提示未知错误&#xff1a;1000正在终止线程 转载于:https://www.cnblogs.com/dennysong/p/5422567.…

分叉并加入Java 7 – JSR 166并发实用程序

Java 7最有趣的改进之一是对并发的更好支持。 使用JSR 166并发实用程序&#xff0c;我们可以对并发进行一些非常有用的改进。 在我看来&#xff0c;fork-join库在软件工程中具有很高的实际应用潜力。 Fork and join为算法提供了非常简单的编程模型&#xff0c;可以将其实现为递…

linux内核源码代码量,Linux内核源代码数量已经超过1000万行

Linux版本2.6.27更新后,人们发现,这一内核的源代码数量已经超过了1000万行.当然,这些行数仅仅是计算机统计出来的行数,包括空白行,为了代码的可读性增加的注释等,当然Linux和所有的长期项目一样,随着时间的推移,旧的代码 会被丢弃和更换,但总体规模来说,Linux的内核在不断增强,…

Python之路【第八篇】:堡垒机实例以及数据库操作

Python之路【第八篇】&#xff1a;堡垒机实例以及数据库操作 堡垒机前戏 开发堡垒机之前&#xff0c;先来学习Python的paramiko模块&#xff0c;该模块机遇SSH用于连接远程服务器并执行相关操作 SSHClient 用于连接远程服务器并执行基本命令 基于用户名密码连接&#xff1a; 12…

关于typedef的使用方法

在计算机编程语言中用来为复杂的声明定义简单的别名。与宏定义有些差异。它本身是一种存储类的keyword&#xff0c;与auto、extern、mutable、static、register等keyword不能出如今同一个表达式中。typedef声明&#xff0c;简称typedef&#xff0c;为现有类型创建一个新的名字&…

ADF BC:创建绑定到业务组件的UI表

在此示例中&#xff0c;我们将展示如何创建绑定到业务组件的简单UI表&#xff08;af&#xff1a;table&#xff09;。 我再次尝试使用简单的标准在网上进行搜索&#xff1a; “如何创建绑定到业务组件ADF 11g的af&#xff1a;table” 我必须承认我没有得到我想要的答案。 信息…

linux驱动程序混合架构,嵌入式系统最小驱动框架(类似linux驱动程序架构)(示例代码)...

2010年就打算把linux里的驱动框架核心代码抠出来的&#xff0c;但是由于懒而且linux代码量大&#xff0c;一直下不了手。最近调试的intel curie里驱动架构也类似linux&#xff0c;代码就少多了&#xff0c;由于工作需要不得不梳理一下这一堆代码&#xff0c;今天花了一下午&…

MyBaits 错误分析

错误原因&#xff1a;在DAO的映射文件中&#xff0c;在映射标签中的type类型写成DAO类了&#xff0c;应该写成javaBean转载于:https://www.cnblogs.com/shuaiandjun/p/5428847.html

超越JUnit –测试框架的替代方案

JUnit是事实上的Java单元测试框架&#xff0c;但是可能有一些新的&#xff08;不是那么新的&#xff09;框架可以用于Web开发。 在采用之前可能要问自己的问题&#xff1a; 它们是否快速&#xff0c;容易开发&#xff0c;因此成本低廉&#xff1f; 他们运行快并因此鼓励采用吗…

tensorflow mnist read_data_sets fails

下载处理mnist数据时出现如下错误 VisibleDeprecationWarning: converting an array with ndim > 0 to an index will result in an error in the future 解决方法&#xff1a; 在input_data.py文件中return numpy.frombuffer(bytestream.read(4), dtypedt) 后添加[0] retur…

斑马打印机linux驱动安装教程,linux-Zebra软件包的基本安装与配置

Zebra是一个路由软件包&#xff0c;提供基于TCP/IP路由服务&#xff0c;支持RIPv1, RIPv2, RIPng, OSPFv2, OSPFv3, BGP- 4,和 BGP-4等众多路由协议。Zebra还支持BGP特性路由反射器(Route Reflector)。除了传统的 IPv4路由协议&#xff0c;Zebra也支持IPv6路由协议。如果运行的…

iOS 改变App状态栏颜色为白色

默认状态栏为黑色&#xff0c;对于某些App不是很美观&#xff0c;变成白色很简单&#xff0c;只需要两个步骤。 1.在Info.plist中添加新项目&#xff0c;View controller-based status bar appearance&#xff0c;Boolean值为No. 2.在AppDelegate的- (BOOL)application:(UIAppl…