spring 面向接口编程_Spring面向方面的编程

spring 面向接口编程

介绍

在理想的面向对象系统中,我们希望将每个对象设计为执行一项特定任务。 但是,除了执行其主要任务之外,对象还执行被动任务,例如日志记录,事务,安全性,缓存等。这些被动活动是必需的,但不是业务逻辑的一部分,被称为“ 跨切问题 ”。

(横切关注点==系统中常用的功能)

横切关注点与业务逻辑分开可以是编写精心设计的解耦代码的重要一步。 让我们思考一下解决交叉切割问题的方法

遗产

继承立即在脑海中弹出,我们可以继承通用功能并在对象中使用它。 但是继承通用功能需要我们设计一个基类。 如果我们在多个地方重用该类,那么以后修改类可能会很困难。

继承==以后很难修改(非弹性代码)

代表团

委派是处理交叉切割问题的更好方法。 记住组成要重于继承,(授权和组成要共同关注)。 但是,然后我们将不得不在许多地方进行调用以委托对象,从而使其变得繁琐。

委派==繁琐

面向方面的编程

这是否意味着我们要喝汤了。 相反,这给我们留下了第三种也是最好的方法,即面向方面的编程。 AOP避免了继承的脆弱性和委派的繁琐性。 AOP在相互交叉的关注点领域大放异彩

什么是AOP?

AOP允许我们将横切关注点模块化到称为Aspects的特殊对象中,从而创建更清晰和分离的代码。 有了适当的方面,对象就不必担心执行被动横切问题,因为AOP会处理所有这些问题。

与AOP有关的术语

像任何成功的技术一样,AOP也具有自己的术语和术语集。 让我们先看一下那些,然后再进行更深入的了解AOP的工作。

  1. 关注点 -这些是基于其功能模块化的系统的一部分。 有两种类型的关注点。 1.核心关注点2.跨领域关注点。 核心关注点与系统的业务逻辑有关,即系统执行的主动任务,例如生成工资单,获取员工记录,进行银行转账等。跨部门关注点是执行主动任务(例如日志记录,缓存)所需的被动任务等等
  2. 连接点–连接点是执行流程中的一个点,其中发生了一些动作,并且有可能应用Aspect(跨领域关注点)。 连接点可以是被调用的方法,抛出异常或对象状态改变。
  3. 建议 – AOP中的每个方面都有其目的,即必须完成的工作。 该作业必须在连接点处应用。 方面的工作或目的称为建议。 除了定义方面的工作之外,建议还定义方面执行工作的时间。 应该在核心关注事项完成执行之前或之后应用作业,还是在两者之前和之后应用作业。
  4. 切入点 –系统中可以有许多连接点,但并非所有方面都由Aspect建议。 Aspect从Pointcut获得帮助,以选择要在其中编织建议的Joinpoint。
  5. 方面 –建议和切入点定义了方面。 正如我们看到的,建议定义了方面的工作以及何时执行。 虽然Pointcut定义了方面编织建议的位置。 因此,工作的内容,时间和地点定义了方面。
  6. 目标 –目标是被建议的对象。 (核心关注)。 在AOP的帮助下,该对象可以自由地执行其主要任务,而不必担心交叉问题。
  7. 代理 –将建议应用于目标对象时,将创建一个代理对象。 AOP容器创建并管理对象的生命周期,程序员无需担心它们。
  8. 编织 –编织是将Advice或Aspect应用于目标对象以创建代理对象的过程。 编织可以在编译时或类加载时或在运行时完成。 通常,Spring AOP在运行时将方面编织到目标对象中。

那是要消化的一长串术语。 在继续之前,请花点时间了解它们。

咨询类型

在沉迷于示例之前的最后一篇文章是了解建议的类型。 主要有4种建议。

  1. 建议之前 –在Joinpoint开始执行之前应用建议之前。 通过实现org.springframework.aop.MethodBeforeAdvice接口来创建BeforeAdvice。 要实现的方法是公共无效(方法m,对象args [],对象目标)抛出Throwable
  2. 返回建议之后–在Joinpoint完成执行之后应用建议之后。 AfterReturningAdvice是通过实现org.springframework.aop.AfterReturningAdvice接口创建的。 ThingableReturning(Method m,Object args [],Object target)抛出之后 ,要实现的方法是公共无效
  3. 引发建议 –当Joinpoint在执行过程中引发异常时,将应用引发建议。
  4. 围绕建议 –此建议围绕Joinpoint执行,并在Joinpoint执行之前和之后执行。 这甚至可以用来控制Joinpoint的调用。

我们将尝试在SpringAOP的帮助下开发一个简单的缓存。 缓存具有三个主要的核心问题。

核心关注点

  1. 将对象保存在缓存中。
  2. 从缓存返回对象。
  3. 从缓存中删除对象。

现在,除了这些核心问题之外,缓存框架还有其他被动任务。 这些被动任务构成了交叉问题。

横切关注点

  1. 达到其大小限制时重新调整缓存大小。 (LRU)实施。
  2. 锁定对象以防止在读取对象时将其删除。
  3. 锁定高速缓存以防止在调整大小时阻止和读取/写入/删除高速缓存。

编码所有这些横切关注点可能是耗时且乏味的,因此让我们简化示例,当缓存已满时,我们将仅实现调整大小逻辑。 因此,在完成示例之后,我们将拥有一个可以放置,获取和删除对象的缓存。 例如,缓存的最大大小已设置为10。 一旦高速缓存存储了10个对象,则对高速缓存的任何添加都将导致通过删除第一个对象来删除(重新调整大小)高速缓存。 调整大小的操作由使用Spring AOP创建的Aspect控制。 这是示例中要遵循的步骤

可以从SVN此处下载示例代码: https : //www.assembla.com/code/weblog4j/subversion/nodes/31/SpringDemos/trunk

  1. 依赖关系 – AOP是spring的核心功能,因此要使Spring AOP正常运行,我们需要的是核心spring jar,因此在您的POM中添加以下依赖关系。
    <dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency>
  2. 核心缓存对象。
    package com.aranin.spring.aop;import java.util.Date;
    import java.util.LinkedHashMap;
    import java.util.Map;public class MyCache {private LinkedHashMap<String, Object> cacheMap = new  LinkedHashMap<String, Object>();private LinkedHashMap<String, Date> timeStampMap = new  LinkedHashMap<String, Date>();/*** defines the max size of hashmap*/private long maxsize = 10;  //should come from properties file or some configuration/*** how long the object should be stored before it is evicted from cache*/private long objectLifeTime = 10000;private boolean lock = false;public LinkedHashMap<String, Object> getCacheMap() {return cacheMap;}public void setCacheMap(LinkedHashMap<String, Object> cacheMap) {this.cacheMap = cacheMap;}public LinkedHashMap<String, Date> getTimeStampMap() {return timeStampMap;}public void setTimeStampMap(LinkedHashMap<String, Date> timeStampMap) {this.timeStampMap = timeStampMap;}public long getMaxsize() {return maxsize;}public void setMaxsize(long maxsize) {this.maxsize = maxsize;}public long getObjectLifeTime() {return objectLifeTime;}public void setObjectLifeTime(long objectLifeTime) {this.objectLifeTime = objectLifeTime;}public boolean isLock() {return lock;}public void setLock(boolean lock) {this.lock = lock;}/*** This method is used to retrive the object from cache* @param key* @return*/public Object get(String key){return this.getCacheMap().get(key);}/*** this method is used for putting an object in cache* @param key* @param object*/public void put(String key, Object object){//get the curr dateDate date = new Date(System.currentTimeMillis());//set object in cacheMapthis.getCacheMap().put(key,object);//put timestamp in cachethis.getTimeStampMap().put(key, date);}public void delete(String key){this.getCacheMap().remove(key);this.getTimeStampMap().remove(key);}public void clearAll(){this.setCacheMap(new  LinkedHashMap<String, Object>());this.setTimeStampMap(new  LinkedHashMap<String, Date>());}/*** remove last 2 entries* not worried about object life time* this is just an example*/public void resize(){System.out.println("inside resize");long size = this.getCacheMap().size();System.out.println("size + " + size);if(size == this.getMaxsize()){System.out.println("max size has reached");Map.Entry<String, Date> firstEntry = this.getTimeStampMap().entrySet().iterator().next();System.out.println("removing : " + firstEntry.getKey() + " value : " + firstEntry.getValue());this.timeStampMap.remove(firstEntry.getKey());Map.Entry<String, Object> firstCEntry = this.getCacheMap().entrySet().iterator().next();System.out.println("removing : " + firstCEntry.getKey() + " value : " + firstCEntry.getValue());this.cacheMap.remove(firstCEntry.getKey());}System.out.println("leaving resize with size : " + this.getCacheMap().size());}
    }

    这个课没什么好说的。 有两个LinkedHashMaps,一个用于存储对象,另一个用于存储将对象推入缓存时的时间戳。 最大大小设置为10,并且具有get,put和delete方法。 还有一个调整大小的方法,Aspect将调用此方法,稍后我们将进行检查。

  3. 调整建议
    package com.aranin.spring.aop;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class ResizeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("invoking " + method.getName() + " on " + target.getClass() + " Object");if(method.getName().equals("put")){System.out.println("before invoking " + method.getName());((MyCache)target).resize();}}
    }

    如您所见,这是建议之前的一种方法。 类实现MethodBeforeAdvice接口,该接口包含单个方法before()。 如果您检查该方法,则在我们调用put方法时,将检查rezise方法是否被调用。

  4. Spring上下文springaopdemo.xml
    <?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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsd"><bean id="resizeAdvice" class="com.aranin.spring.aop.ResizeAdvice" /><bean id="myCache" class="com.aranin.spring.aop.MyCache" /><bean id="myAOPCache"class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="myCache" /><property name="interceptorNames"><list><value>resizeAdvice</value></list></property></bean>
    </beans>

    如果您注意到上述xml文件,则MyCache和ResizeAdvice均已注册为spring bean。 文件中的主要bean是myAOPCache。 这是spring aop在核心类上应用建议后创建的代理对象。 代理对象由ProxyFactoryBean类创建。 我们将myCache对象的引用传递给代理对象,并注册所有将应用于代理类的建议。

  5. 最后,让我们检查Client,这将有助于我们运行此演示。
    package com.aranin.spring.aop;import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.FileSystemXmlApplicationContext;public class MyCacheClient {public static void main(String[] args){ApplicationContext springcontext = new FileSystemXmlApplicationContext("D:/samayik/SpringDemos/src/main/resources/springaopdemo.xml");MyCache myCache = (MyCache)springcontext.getBean("myAOPCache");myCache.put("1", "1");myCache.put("2", "2");myCache.put("3", "3");myCache.put("4", "4");myCache.put("5", "5");myCache.put("6", "6");myCache.put("7", "7");myCache.put("8", "8");myCache.put("9", "9");myCache.put("10", "10");System.out.println((String)myCache.get("1"));System.out.println((String)myCache.get("2"));System.out.println((String)myCache.get("10"));myCache.put("11", "11");System.out.println((String)myCache.get("1"));System.out.println((String)myCache.get("2"));System.out.println((String)myCache.get("10"));System.out.println((String)myCache.get("11"));}}

    在此类中,我们启动弹簧容器并加载spingaopdemo.xml中存在的bean。 我们在缓存中推送10个对象,当我们尝试推送第11个对象时,第一个对象将被删除并插入第11个对象。 输出很大,所以我没有发布输出。 上课并检查输出是否令您满意。

摘要

在这篇文章中,我们学习了如何使用面向方面的编程更好地处理交叉问题。 AOP是一个强大的概念,可让我们编写更简洁,更解耦的代码。 AOP不提供任何新内容。 它所做的只是将业务逻辑与系统必须执行的其他普通任务分离。 它可以重用实现系统范围内交叉关注点的代码。 我们还学习了与AOP相关的各种术语。 最后但并非最不重要的一点是,我们看到了一个简单的示例,在该示例中,我们使用Spring AOP创建了一个简单的方法前建议,并将其应用于管理缓存系统。

注意

您可以自由使用和分发此代码中开发的缓存系统。 尽管不建议在生产系统中使用它。

一如既往,我一直希望这篇文章作为集体学习的启动平台,随意发表一两个关于您对AOP的看法以及如何计划在代码中使用它的评论。 祝您阅读愉快。

参考: Weblog4j博客上的JCG合作伙伴 Niraj Singh的《 Spring面向方面的编程》 。

翻译自: https://www.javacodegeeks.com/2013/10/aspect-oriented-programming-with-spring-2.html

spring 面向接口编程

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

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

相关文章

Nutshell中的Java 8语言功能-第2部分

编者注&#xff1a;您也可以在此处检查Part-1。 嗨&#xff0c;朋友们&#xff0c;这是简明系列的Java 8语言功能的第2部分。 在这里&#xff0c;我们将讨论Java 8的以下功能&#xff1a; 接口中的静态方法 流 1.接口中的静态方法 什么是静态方法&#xff1f; 静态方法是属…

概率

概率 概率质量函数&#xff08;probability mass function, PMF&#xff09;针对的是离散变量 常见的离散随机变量分布的PMF函数&#xff1a;伯努利分布&#xff0c;二项分布&#xff0c;泊松分布。 概率密度函数&#xff08;probability density function, PDF&#xff09;针…

oracle impdp导入时卡住,Oracle:impdp导入等待statement suspended, wait error to be cleared

用数据泵impdp往开发数据库导数据&#xff0c;但导入到INDEX时感觉卡住不动了Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX----查看状态&#xff0c;Completed Objects: 33一直没有变化。Import> statusJob: SYS_IMPORT_FULL_01Operation: IMPORTMode: FULLStat…

梯度下降法、最速下降法

梯度下降法 最优化问题是求解函数极值的问题&#xff0c;包括极大值和极小值。相信所有的读者对这个问题都不陌生&#xff0c;在初中时我们就学会了求解二次函数的极值&#xff08;抛物线的顶点&#xff09;&#xff0c;高中时学习了幂函数&#xff0c;指数函数&#xff0c;对…

php ajax 表格编辑,php ajax表格实时编辑 PHP Ajax实现表格实时编辑

想了解PHP Ajax实现表格实时编辑的相关内容吗&#xff0c;佛祖的腿毛在本文为您仔细讲解php ajax表格实时编辑的相关知识和一些Code实例&#xff0c;欢迎阅读和指正&#xff0c;我们先划重点&#xff1a;php,ajax表格实时编辑,ajax实现表格编辑&#xff0c;下面大家一起来学习吧…

jpa和hibernate_使用JPA和Hibernate有效删除数据

jpa和hibernate您可能会遇到必须对关系数据库中存储的大量数据集执行批量删除的情况。 如果您将JPA与Hibernate一起用作基础OR映射器&#xff0c;则可以尝试通过以下方式调用EntityManager的remove&#xff08;&#xff09;方法&#xff1a; public void removeById(long id) …

超越函数

代数数 在数论中&#xff0c;超越数是指任何一个不是代数数的数字&#xff08;通常它是复数&#xff09;。它满足以下条件——只要它不是任何一个整系数代数方程的根&#xff0c;它即是超越数。最著名的超越数是e以及π。 超越数 超越数的例子 所有超越数构成的集是一个不可数…

无服务器-仅仅是构建现代应用程序的一种方法?

如果搜索“无服务器”&#xff0c;则会发现无服务器是构建现代应用程序的一种新的流行方式。 无服务器真的是新的吗&#xff1f; 无服务器是指您无需担心服务器的概念-无需置备&#xff0c;部署和维护服务器。 显然有服务器&#xff0c;但是您无需考虑或担心它们&#xff0c;运…

linux查看用户的操作记录,Linux下查看用户登陆后的操作记录

Linux下查看用户登陆后的操作记录  在linux系统的环境下&#xff0c;不管是root用户还是其它的用户只有登陆系统后用进入操作我们都可以通过命令history来查看历史记录&#xff0c;可是假如一台 服务器多人登陆&#xff0c;一天因为某人误操作了删除了重要的数据。这时候通过…

只需5分钟即可启动并运行分层架构:: Spring Boot第1部分

这是一个分为两部分的系列&#xff0c;其中我将展示如何使用Spring Boot创建分层架构。 什么是分层体系结构&#xff1a;简而言之&#xff0c;当我们构建企业应用程序时&#xff0c;我们维护不同的层以封装特定于层的逻辑&#xff0c;这样就不会溢出到另一层。 当我们考虑企业…

机器学习算法、深度学习算法涉及的数学知识

微积分基础 导数的定义 左导数、右导数、可导函数 导数几何意义、物理意义 基本函数求导公式 四则运算法则 复合函数求导法则 神经网络激活函数的导函数求解 高阶导数 导数与函数单调性 极值定理 导数与函数凹凸性 一元函数泰勒展开 线性代数基础 向量与其运算 行向量和列向…

linux设置默认的首页文件,Linux 设置Firefox主页

Linux 设置Firefox主页在Linux系统中&#xff0c;当用户启动Firefox主页时&#xff0c;会自动打开Firefox默认设置的主页。当然&#xff0c;用户也可以通过Firefox的首选项&#xff0c;手动将Firefox主页设置为自己喜欢的或经常访问的网页。在本单元练习中&#xff0c;将Firefo…

spring 2.2 改进_Spring 4中@ControllerAdvice的改进

spring 2.2 改进在Spring 4的许多新功能中&#xff0c;我发现了ControllerAdvice的改进。 ControllerAdvice是Component的特殊化&#xff0c;用于定义适用于所有RequestMapping方法的 ExceptionHandler&#xff0c; InitBinder和ModelAttribute方法。 在Spring 4之前&#xff0…

向量范数与矩阵范数

一、向量的范数 1.1 定义 1.2 举例 首先定义一个向量为&#xff1a;a[-5&#xff0c;6&#xff0c;8, -10] 1.2.1 向量的1范数 向量的1范数即&#xff1a;向量的各个元素的绝对值之和&#xff0c;上述向量a的1范数结果就是&#xff1a;29&#xff0c;MATLAB代码实现为&…

不同磁盘目录共享linux,linux下实现磁盘共享(mount)

准备两台centos6.6 A(192.168.199.2)、B(192.168.199.3)&#xff0c;A做服务端、B做客户端。一台ubuntu14.04 C(192.168.199.4)C做客户端。A、B安装nfs对应服务yum -y install nfs-utils rpcbind####C安装nfs-kernel-serverapt-get install nfs-kernel-server####A设置nfs、por…

苹果linux桌面文件夹,Ubuntu 10.04下一键安装Mac OS X主题桌面

不久前的《Ubuntu 10.04下Mac OS X风格桌面美化安装》遭到网友的砖头&#xff0c;认为和Mac OS X风格桌面美化安装根本没有关系。本来是要跟这篇一起发布的&#xff0c;一等就等了这么长&#xff0c;下面我们来看下在Ubuntu 10.04下一键安装Mac OS X主题桌面的工具Epidermis th…

示性函数、共轭函数、对偶范数、共轭

示性函数(Indicator function) 共轭函数 对偶范数 几个常用公式 共轭&#xff08;conjugate&#xff09; 所谓“轭”&#xff0c;指的是古代牛车上放在并行的牛脖颈上的曲木。共轭关系&#xff0c;通俗来说一般用以描述两件事物以一定规律相互配对或孪生&#xff08;一般共轭对…

Redis-实践知识

转自极客时间Redis 亚风 原文视频&#xff1a;https://u.geekbang.org/lesson/535?article681062 Redis最佳实践 普通KEY Redis 的key虽然可以自定义&#xff0c;但是最好遵循下面几个实践的约定&#xff1a; 格式&#xff1a;[业务名称]:[数据名]:[id] 长度不超过44字节 不…

MicroProfile OpenAPI上的Swagger UI

MicroProfile OpenApi为我们提供了一种使用OpenApi 3描述我们JAX-RS API的标准化方法。如果您以前使用过swagger-jaxrs和swagger-annotations &#xff0c;由于OpenApi是基于Swagger构建的&#xff0c;因此您会感到非常熟悉。 2015年11月5日&#xff0c;SmartBear与3Scale&…