使用Spring AspectJ和Maven进行面向方面的编程

Spring框架附带AOP支持。 实际上,如Spring参考文档中所述 ,

Spring的关键组件之一是AOP框架。 尽管Spring IoC容器不依赖于AOP,这意味着您不需要使用AOP,但AOP是对Spring IoC的补充,以提供功能强大的中间件解决方案。 AOP在Spring框架中用于…

  • …提供声明性企业服务,尤其是代替EJB声明性服务。 此类服务中最重要的是声明式事务管理。  
  • …允许用户实现自定义方面,并通过AOP补充其对OOP的使用。

尽管如此,与完整的AOP实现(例如AspectJ)相比, Spring AOP框架还是有某些限制。 人们在使用Spring AOP框架时遇到的最常见问题源于以下事实: Spring AOP是“基于代理的”。 换句话说,当将bean用作依赖项并且应通过特定方面建议其方法时,IoC容器将注入“方面感知” bean代理,而不是bean本身。 为了对用户透明地对代理bean实例执行方法调用,以便在将调用委派给实际的“代理” bean之前和/或之后执行方面逻辑。

此外, Spring AOP框架使用JDK动态代理或CGLIB创建给定目标对象的代理。 第一个只能为接口创建代理,而第二个可以代理具体类,但有一定的限制。 特别是,如Spring参考文档中所述 ,

如果要代理的目标对象实现至少一个接口,则将使用JDK动态代理。 目标类型实现的所有接口都将被代理。 如果目标对象未实现任何接口,则将创建CGLIB代理。

总而言之,在使用Spring AOP框架时,您应该牢记两个重要事项:

  1. 如果您的“代理” bean实现了至少一个接口,则只能将代理bean强制转换为该接口。 如果尝试将其强制转换为“代理” bean类,则应期望在运行时引发ClassCastException。 尽管如此, Spring AOP框架提供了强制CGLIB代理的选项,但有上述限制(请参阅Spring参考文档的相关章节)
  2. 方面不适用于术中呼叫。 这意味着代理无法拦截来自相同“代理” bean的另一个方法的方法的调用

我们建议克服以上问题的方法是使用AspectJ编织。 换句话说,将方面逻辑直接注入到目标类中,并消除了代理所有方法的必要性。 有三种方法可以注入AspectJ方面所隐含的指令:

  1. 编译时间编织–通过AspectJ编译器编译目标源或方面类
  2. 编译后编织–向已编译的类注入方面指令
  3. 加载时间编织–在类加载期间向字节码注入方面指令

可以使用上述任何方法。 在本教程中,我们将介绍如何在Spring和Maven中使用AspectJ编译时编织。 我们将实现最小的“问候” Spring服务和相关的“问候” AspectJ方面。 Spring服务方法调用将被AspectJ方面拦截。 AspectJ方面将使用其自己的“问候”消息来丰富Spring服务的“问候”消息。 AspectJ方面的“问候”消息将从Spring容器中注入,只是为了展示如何将Spring依赖项注入到AspectJ方面。

已经为其bean服务实现了方面的Spring用户可以透明地切换到AspectJ ,这意味着由于Spring AOP框架使用AspectJ切入点表达语言的子集而无需编写任何特殊代码,并且@AspectJ Spring方面完全符合AspectJ的编织要求。 。

我们首选的开发环境是Eclipse ,因此,必须先安装具有Maven支持的Eclipse 。 用于Eclipse的Maven插件的安装不在本教程的讨论范围内,因此将不予讨论。 但是,您将需要以下组件:

  1. 从这里蚀
  2. 从这里开始 ,Eclipse的Maven插件

在本教程中,我们将使用Eclipse Galileo,“ m2eclipse” Maven Integration for Eclipse插件版本0.10.0,Spring版本3.0.1,aspectjrt版本1.6.7和Aspectj-maven-plugin版本1.3。

让我们开始,

  1. 创建一个新的Maven项目,转到File? 项目? Maven? Maven项目
  2. 在向导的“选择项目名称和位置”页面中,确保未选中“创建简单项目(跳过原型选择)”选项,单击“下一步”以继续使用默认值
  3. 在向导的“选择原型”页面中,在“目录”下拉列表中选择“ Nexus Indexer”,并在刷新原型选择区域后,从“ org.codehaus.mojo”中选择“ webapp-jee5”原型。原型”。 您可以使用“过滤器”文本框来缩小搜索结果范围。 点击“下一步”继续
  4. 在向导的“输入工件ID”页面中,您可以定义项目的名称和主程序包。 我们将“ Group Id”变量设置为“ com.javacodegeeks”,将“ Artifact Id”变量设置为“ aspectjspring”。 前面提到的选择组成了主项目包“ com.javacodegeeks.aspectjspring”和项目名“ aspectjspring”。 点击“完成”退出向导并创建您的项目

让我们回顾一下有关Maven Web项目结构的一些事情

  1. / src / main / java文件夹包含应用程序动态内容的源文件
  2. / src / test / java文件夹包含用于单元测试的所有源文件
  3. / src / main / webapp文件夹包含用于创建有效的Web应用程序的基本文件,例如“ web.xml”
  4. / target文件夹包含已编译和打包的可交付成果
  5. “ pom.xml”是项目对象模型(POM)文件。 包含所有项目相关配置的单个文件。

为了在运行时正确使用Spring ,我们必须向Web应用程序提供所有必需的库。 打开“ pom.xml”的图形编辑器并执行以下更改:

  1. 在POM编辑器的“概述”页面上的“属性”部分中找到并执行以下更改:
  • 创建一个名称为org.springframework.version且值为3.0.1.RELEASE的新属性
    • 根据您的Java运行时环境的版本,创建一个名称为maven.compiler.source的新属性,并赋值为value,我们将使用1.6
      • 根据您的Java运行时环境的版本创建一个名称为maven.compiler.target的新属性,并将其值设置为value,我们将使用1.6
        • 导航到POM编辑器的“ Dependencies”页面,并创建以下依赖关系(您应在该页面的“ Dependency Details”部分的“ GroupId”,“ Artifact Id”和“ Version”字段中进行填充):
          • 组ID: org.springframework工件ID: spring-web版本: $ {org.springframework.version}
            • ID:org.aspectj工件ID:aspectjrt版本:1.6.7
            1. 导航到POM编辑器的“插件”页面,并创建以下插件(您应在该页面的“插件详细信息”部分的“ GroupId”,“工件ID”和“版本”字段中进行填充):
              • 组ID: org.codehaus.mojo工件ID: aspectj-maven-plugin版本: 1.3
              1. 在POM编辑器的“插件”页面上,选择新创建的插件(从“插件”部分中),并将其绑定到编译执行目标。 为此,请找到“执行”部分并创建一个新的执行。 在“执行详细信息”部分,创建一个新目标并将其命名为“ compile
              2. 新创建的插件需要进行最后的配置更改。 为了使AspectJ编译器正确地编织方面类,我们必须定义所使用的Java运行时环境版本。 我们需要编辑“ pom.xml”文件来执行更改。 选择POM编辑器的“ pom.xml”页面,找到新创建的插件,并如下进行更改:
              3. <plugin><groupId>org.codehaus.mojo</groupId><artifactId>aspectj-maven-plugin</artifactId><version>1.3</version><configuration><source>${maven.compiler.source}</source><target>${maven.compiler.target}</target></configuration><executions><execution><goals><goal>compile</goal></goals></execution></executions>
                </plugin>
              4. 最后,如下所示更改“ maven-compiler-plugin”:
              5. <plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>2.0.2</version><configuration><source>${maven.compiler.source}</source><target>${maven.compiler.target}</target></configuration>
                </plugin>

                如您所见, Maven以声明方式管理库依赖关系。 创建本地存储库(默认情况下,位于{user_home} /。m2文件夹下),所有必需的库都从公共存储库下载并放置在该库中。 此外,库内的依赖关系会自动解决和处理。

                下一步是为Web应用程序提供挂钩,以便在启动时加载Spring上下文。

                在/ src / main / webapp / WEB-INF下找到“ web.xml”文件,并添加以下内容:

                为了在启动时加载Spring上下文,

                <listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
                </listener>

                现在让我们创建将驱动Spring容器的applicationContext.xml文件。 在/ src / main / webapp / WEB-INF目录下创建文件。 下面是一个示例“ applicationContext.xml”

                <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"xmlns:task="http://www.springframework.org/schema/task"xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"><context:component-scan base-package="com.javacodegeeks.aspectjspring" /><bean class="com.javacodegeeks.aspectjspring.aspects.GreetingAspect" factory-method="aspectOf"><property name="message" value="Hello from Greeting Aspect"/></bean></beans>

                这里要注意的事情:

                1. 将context:component-scan元素的base-package属性更改为项目的基本包,以便扫描Spring组件
                2. 仅当我们要向它们注入依赖项时,才必须在“ applicationContext.xml”中定义我们的方面
                3. AspectJ表示术语“方面关联”。 它定义了如何管理方面状态。 支持以下状态关联:
                • 每个JVM –构造和使用一个共享的方面实例(默认)
                • 每个对象–每个建议对象的方面都有其自己的状态
                • 每个控制流–方面在每个特定控制流中都有自己的状态
                  所有AspectJ方面类都具有“ hasAspect()”和“ aspectOf()”静态方法。 这些方法由AspectJ编译器/加载时间编织器隐式生成。 因此,对于默认的方面状态,可以使用“ aspectOf()”方法来检索一个方面的实例

                现在让我们创建“问候” Spring服务和相关的“问候” AspectJ方面。 在主程序包下创建一个名为“服务”的子程序包,并将“ GreetingService”类放在此处。 下面是一个示例“问候”服务:

                package com.javacodegeeks.aspectjspring.services;import org.springframework.stereotype.Service;@Service("greetingService")
                public class GreetingService {public String sayHello() {return "Hello from Greeting Service";}}

                在主包下创建一个名为“ aspects”的子包,并将“ GreetingAspect”类放在此处。 下面是一个示例“问候”方面:

                package com.javacodegeeks.aspectjspring.aspects;import org.aspectj.lang.ProceedingJoinPoint;
                import org.aspectj.lang.annotation.Around;
                import org.aspectj.lang.annotation.Aspect;@Aspect
                public class GreetingAspect {private String message;public void setMessage(String message) {this.message = message;}@Around("execution(* com.javacodegeeks.aspectjspring.services.GreetingService.*(..))")public Object advice(ProceedingJoinPoint pjp) throws Throwable {String serviceGreeting = (String) pjp.proceed();return message + " and " + serviceGreeting;}}

                最后,在/ src / main / webapp文件夹下找到项目的主网页“ index.jsp”,并进行如下更改:

                <%@ page language="java" import="org.springframework.web.context.WebApplicationContext, org.springframework.web.context.support.WebApplicationContextUtils, com.javacodegeeks.aspectjspring.services.GreetingService"%>
                <%@page contentType="text/html" pageEncoding="UTF-8"%>
                <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><% 
                WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
                GreetingService greetingService = (GreetingService) webApplicationContext.getBean("greetingService");
                %>
                <html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>JSP Page</title></head><body><h1>Test service invoked and greets you by saying : <%=greetingService.sayHello()%></h1></body>
                </html>

                这里要注意的事情:

                1. 页面加载后,我们检索Spring Web应用程序上下文,并查找“问候”服务。 我们要做的就是调用“ sayHello()”方法,从我们的方面和服务中查看合并的问候消息

                要构建应用程序,请右键单击您的项目? 运行为? Maven包

                要部署Web应用程序,只需将“ .war”文件从“ target”目录复制到Apache – Tomcat “ webapps”文件夹

                午餐应用程序将您的浏览器指向以下地址

                http:// localhost:8080 / {application_name} /

                如果一切顺利,您应该会看到显示以下内容的主网页:

                “测试服务被调用并打招呼:“ Greeting Aspect向您问好,Greeting Service向您问好”

                您可以从这里下载项目

                希望你喜欢

                贾斯汀

                相关文章 :

                • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程
                • GWT Spring和Hibernate进入数据网格世界
                • Spring3 RESTful Web服务
                • GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
                • 带有Spring和Maven教程的JAX–WS

                翻译自: https://www.javacodegeeks.com/2010/07/aspect-oriented-programming-with-spring.html

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

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

              相关文章

              hadoop5--mapreduce设计模式

              运行结果附图 本节课程主要内容为学习MapReduc设计模式&#xff0c;并编写java程序对日志文件进行处理。 课本上介绍的MapReduce的设计模式主要包含:计数(Counting),分类(Classification),过滤处理(Filtering),排序(Sorting),去重计数(Distinct Counting),相关计数(Cross-Corre…

              ES5中新增的Array方法详细说明

              http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/转载于:https://www.cnblogs.com/lmw425317/p/5339539.html

              jqGrid,REST,AJAX和Spring MVC集成

              两年多以前&#xff0c;我写了一篇关于两个如何在Struts2中实现优雅的CRUD的文章。 实际上&#xff0c;我必须就该主题写两篇文章&#xff0c;因为该主题如此广泛。 今天&#xff0c;我采用了一套更为流行的&#xff0c;完善的框架和库&#xff0c;采用了更为轻量级的现代方法。…

              Java-马士兵设计模式学习笔记-代理模式--动态代理 修改成可以代理任意接口

              一、概述 1.目标&#xff1a;把Proxy修改成可以代理任意接口及其任意方法 2.思路&#xff1a; (1)代理任意接口&#xff1a;把接口类型作为参数传给Proxy的newProxyInstance(Class interfze) (2)代理任意方法&#xff1a;用interfze.getMethods()取出所有方法&#xff0c;拼接实…

              PTA习题

              PTA习题 PTA浙大版《C语言程序设计&#xff08;第3版&#xff09;》 题目集5-6 水仙花数是指一个N位正整数&#xff08;N≥3&#xff09;&#xff0c;它的每个位上的数字的N次幂之和等于它本身。 本题要求编写两个函数&#xff0c;一个判断给定整数是否水仙花数&#xff0c;…

              acdream 1409 Musical 状压DP

              链接&#xff1a;http://acdream.info/problem?pid1409 题意&#xff1a;整个国家有n座城市&#xff0c;每座城市有三种粉丝。 第一种一周看一场音乐剧&#xff0c;挑选的音乐剧是已经在周围城市播放上演过的次数最多的音乐剧中的随机一个。 另外一种每天看一场音乐剧&#xf…

              真正的模块化Web应用程序:为什么没有开发标准?

              OSGI &#xff0c; SpringSource &#xff0c; Jboss模块 &#xff0c;J2EE和清单永远不会结束。所有这些技术都向他们的最终用户/开发人员保证了相同的东西&#xff0c;或多或少是Java模块化Web应用程序&#xff08;&#xff1f;&#xff09;。 但是&#xff0c;我们当中有多少…

              C语言5-7习题

              本题要求实现一个函数&#xff0c;用下列公式求cos(x)的近似值&#xff0c;精确到最后一项的绝对值小于e&#xff1a; #include <stdio.h> #include <math.h>double funcos( double e, double x );int main() { double e, x;scanf("%lf %lf", &…

              JDBC批处理executeBatch

              JDBC运行SQL声明&#xff0c;有两个处理接口&#xff0c;一PreparedStatement,Statement,一般程序JDBC有多少仍然比较PreparedStatement 只要运行批处理&#xff0c;PreparedStatement少一点Statement ps conn.prepareStatement(sql); for(int i 0;i<10;i){ ps.setString(…

              BC div2补题以及 复习模除 逆元__BestCoder Round #78 (div.2)

              第一题没话说 智商欠费 加老柴辅导终于过了 需要在意的是数据范围为2的63次方-1 三个数相加肯定爆了 四边形的定义  任意边小于其余三边之和 换句话说就是  最长边小于其余三边之和 这样的话问题转化为 最长边依次减其余三边的结果是否小于等于0 还有一点是题目出现0边 即最…

              习题6-1 分类统计字符个数 (15 分)

              本题要求实现一个函数&#xff0c;统计给定字符串中英文字母、空格或回车、数字字符和其他字符的个数。 函数接口定义&#xff1a; void StringCount( char s[] );其中 char s[] 是用户传入的字符串。函数StringCount须在一行内按照 letter 英文字母个数, blank 空格或回车…

              Servlet 3.0异步处理可将服务器吞吐量提高十倍

              Servlet是Java中处理服务器端逻辑的主要组件&#xff0c;新的3.0规范引入了一些非常有趣的功能&#xff0c;其中异步处理是最重要的功能之一。 可以利用异步处理来开发高度可伸缩的Web应用程序。 使用此功能可以有效地构建Web 2.0站点和AJAX应用程序。 我们的JCG合作伙伴之一To…

              使用secureCRT连接VMware-Ubuntukylin虚拟机

              使用SecureCRT连接VMware时总是提醒主机拒绝连接。这时可以使用sudo apt-get install openssh-server openssh-client&#xff0c;在主机上安装ssh. 安装成功后&#xff0c;可以连接到主机了。 如果显示远程主机拒绝连接。则可以使用如下方法。 VMware里面装的是Ubuntukylin版本…

              加载音频Audio

              var cameraAudio new Audio(); cameraAudio.src camera.wav;// 设置音频对象的属性,预加载视频 var options_audio { preload : auto } for(var key in options_audio){ if(options_audio.hasOwnProperty(key) && (key in cameraAudio)){ cameraAudio[key] opti…

              习题6-2 使用函数求特殊a串数列和 (20 分)

              给定两个均不超过9的正整数a和n&#xff0c;要求编写函数求aaaaaa⋯aa⋯a&#xff08;n个a&#xff09;之和。 int fn( int a, int n ); int SumA( int a, int n );其中函数fn须返回的是n个a组成的数字&#xff1b;SumA返回要求的和。 我的代码&#xff1a; int fn( int a, i…

              Java中可怕的双重检查锁定成语

              本文讨论的问题不是新问题&#xff0c;但即使是经验丰富的开发人员也仍然很棘手。 单例模式是常见的编程习惯。 但是&#xff0c;当与多个线程一起使用时&#xff0c;必须进行某种类型的同步&#xff0c;以免破坏代码。 Khangaonkar报告中的 JCG合作伙伴Manoj Khangaonkar在一篇…

              国内有哪些好的刷题网站?

              http://www.zhihu.com/question/25574458 Luau Lawrence&#xff0c;Data Mining 弱鸡 / PhDNTU 温梦强、石一帆、知乎用户 等人赞同 - Welcome To PKU JudgeOnline 北京大学的Online Judge。POJ上面的题目有点老了&#xff0c;但好处是做的人多&#xff0c;经典算法题多&…

              IE版本判断

              我们常常会在网页的HTML里面看到形如[if lte IE 9]……[endif]的代码&#xff0c;表示的是限定某些浏览器版本才能执行的语句&#xff0c;那么这些判断语句的规则是什么呢&#xff1f;请看下文&#xff1a; <!--[if !IE]><!--> 除IE外都可识别 <!--<![endif]…

              Js 流程控制

              流程控制 顺序、分支、循环 顺序结构 代码一行一行从上往下执行并解析 分支结构 if语句 switch语句 if语句 单分支 if(条件表达式){ //语句块 } 含义&#xff1a;当条件表达式为真的时候就执行里面的语句块 示例&#xff1a; 双分支&#xff1a; if(条件表达式){ //语句块1 }el…

              习题6-3 使用函数输出指定范围内的完数 (20 分)

              本题要求实现一个计算整数因子和的简单函数&#xff0c;并利用其实现另一个函数&#xff0c;输出两正整数m和n&#xff08;0<m≤n≤10000&#xff09;之间的所有完数。所谓完数就是该数恰好等于除自身外的因子之和。例如&#xff1a;6123&#xff0c;其中1、2、3为6的因子。…