spring aop实践

在课堂设计过程中,我们应就每个班级的职责分配做出决定。 如果我们选择的不错,系统将更易于理解,维护和扩展。

我们几乎所有的项目都有一个持久层,即关系数据库,文档存储或仅XML文件。 通常,您将使用DAO模式在业务对象和数据存储之间实现抽象接口。

在这篇文章中,但我将解释另一种可以代替DAO模式使用的模式。 活动记录模式是一种体系结构模式,它迫使您对模型类实施CRUD操作,因此模型类本身负责保存,删除和从数据库加载。

要实现此模式,有许多策略可以遵循,但是对我来说,最好的方法是使用面向方面的编程 ,因为我们仍然保持关注点分离,有利于隔离的单元测试,而不破坏封装。

面向方面的编程需要将程序逻辑分解为不同的部分。 这些部分被称为横切关注点,因为它们“ 跨越 ”程序中的多个抽象。 横切关注点的示例可以是日志记录,事务管理器错误管理器拆分大型数据集 。 对于在这里没有太多秘密的方面的人们来说,要使用它们,只需创建定义建议和切入点的方面,然后就可以执行您的方面了。

我想我们大多数人都使用了上一段中所述的面向方面的编程,但是使用ITD(类型间声明)功能的人会更少。

类型间声明提供了一种表达横切关注点的方法,这些关注点影响了模块的结构,从而使程序员可以声明另一个类的成员。

正如我们在我的国家说“ 不好说,但很好理解 “,ITD是从一个方面宣布新的组件属性,方法,注解 )的方式。

AspectJ是Java 的面向方面的扩展。 AspectJ支持ITD ,因此在本文中将使用它。 此外,我建议您安装AJDT插件,因为它将帮助您开发方面,并快速概述了哪些Java类已被方面化。

如果您不了解什么是ITD ,请不用担心,这是一个典型的概念示例,最好通过示例来理解。

让我们从一个简单的例子开始:

想象一下必须为汽车建模。 您将拥有一个带有某些属性的汽车类,在此示例中,三个属性( vin号,行驶里程model )就足够了。

public class Car {public void setVin(String vin) {this.vin = vin;}public String getVin() {return this.vin;}private String vin;public void setMileNum(int mileNum) { this.mileNum = mileNum;}public int getMileNum() {return this.mileNum;}private int mileNum;public void setModel(String model) {this.model = model;}public String getModel() {return this.model;}private String model; }

这是一个具有三个属性以及它们的gettersetterPOJO

现在我们要添加持久层,但是在这种情况下,我们将POJO持久保存在XML文件而不是数据库中。 因此,应将Car对象转换为XML流。 为此,将使用JAXB批注。 对于那些不知道的人, JAXB允许开发人员将Java类映射到XML表示,反之亦然。

我确信,想到的第一个想法是使用@XmlRootElement注释Car类(在JAXB中映射根元素的注释)。 不要那样做,使用方面 。 您的第一个任务是尝试维护Car文件尽可能简单。 要使用ITD添加注释,很简单:

public aspect Car_Jaxb {declare @type: Car: @XmlRootElement;
}

使用@type可以公开注释哪个成员。 在这种情况下,只能上课。 其他方法是@method@constructor@field 。 然后元素模式应该被注释,在这种情况下是Car类,但是您可以使用任何正则表达式,例如o rg.alexsotob .. *。 最后是注释

下一步是使用JAXB类来编组/解组对象。 在此示例中,我使用spring-oxm软件包,简要地您将了解原因。 Spring-oxmspring-core的一部分,其中包含用于处理O / X Mapping的类

这个spring模块为每个受支持的Xml绑定包含一个类。 在我们的情况下, Jaxb2Marshaller用作编组器和解组器。

您可能正在考虑创建一个服务类,在其中注入Jaxb2Marshaller实例。 该服务将包括两个方法(保存和加载),以Car类作为参数或返回值。 抱歉,这样做是要实现DAO模式。 让我们实现Active Record模式方法。 正如您可能会想到的, aspectj可以帮助您避免将概念混入同一源文件中。

让我们更新以前的方面文件,以便JAXB所需的所有逻辑都在同一文件中。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;public aspect Car_Jaxb {declare @type: Car: @XmlRootElement;@Autowiredtransient Jaxb2Marshaller Car.marshaller;public void Car.save(OutputStream outputStream) throws IOException {this.marshaller.marshal(this, new StreamResult(outputStream));}public Car Car.load(InputStream inputStream) throws IOException {return (Car)this.marshaller.unmarshal(new StreamSource(inputStream));}}

看到除了注释Car类之外,我们还创建了两个方法和一个带注释的属性。 属性必须遵循与方法,< 类名 >点(。)和< 属性名 >相同的规则。 请注意,在这种情况下,属性是瞬态的,因为不应绑定到XML文件中。

最后一步是在spring上下文文件中配置marshaller

<?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:oxm="http://www.springframework.org/schema/oxm"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><oxm:jaxb2-marshaller id="marshaller"><oxm:class-to-be-bound name="org.alexsotob.itd.Car"/></oxm:jaxb2-marshaller></beans>

没有太多秘密。 现在让我们编写一个单元测试代码。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/context.xml")
public class CarOxmBehaviour {@Testpublic void shouldSaveCarToXml() throws Exception {//GivenCar car = new Car();car.setMileNum(1000);car.setModel("Ferrari");car.setVin("1M8GDM9AXKP042788"); //From http://en.wikipedia.org/wiki/Vehicle_Identification_Number//WhenByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();car.save(byteArrayOutputStream);//ThenString expectedMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><car><mileNum>1000</mileNum><model>Ferrari</model><vin>1M8GDM9AXKP042788</vin></car>";String xmlMessage = byteArrayOutputStream.toString("UTF-8");assertThat(the(xmlMessage), isEquivalentTo(the(expectedMessage)));  }}

用令人惊讶的NullPointerException运行红色的junit类和BOOMMarshaller是在Spring上下文中创建的,但未注入Car类(Car不是由spring 容器管理的,因此无法注入)。 现在,我想您是对自己说的:“ 我告诉您,服务层会更好,因为它将由Spring进行管理,并且自动装配功能会非常完美 。” 但是,拭目以待。 如何使用spring-aspects模块? Spring Aspects包含一个注释驱动的方面( @Configurable ),允许任何对象的依赖项注入,无论是否由容器控制。 因此,让我们应用最后两个更改,应用程序将运行。

首先是创建一个新的aspectj文件,以将Car类注释为Configurable

import org.springframework.beans.factory.annotation.Configurable;public aspect Car_Configurable {declare @type: Car: @Configurable;}

最后修改spring上下文文件以允许@Configurable注释。

<?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:oxm="http://www.springframework.org/schema/oxm"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"><oxm:jaxb2-marshaller id="marshaller"><oxm:class-to-be-bound name="org.alexsotob.itd.Car"/></oxm:jaxb2-marshaller><context:spring-configured></context:spring-configured>
</beans>

添加< context:spring-configured > </ context:spring-configured >命名空间就足够了。 结果,每当您实例化一个对象(通过“ new ”关键字)时,Spring都会尝试对该对象执行依赖注入。

现在再次运行单元测试,绿色将侵入您的计算机:D。

ITD是一个很好的解决方案,可以自己负责设计类。 它为您提供了编写可维护且易于理解的代码的机会,而不会丢失封装。 当然,您应该注意不要在方面类中具有很高的耦合,而应将它们转换为“上帝类”。

注意,实现相同的方法但使用关系数据库,就像将Jaxb2Marshaller更改为EntityManager一样简单。

我希望您发现这篇文章有用。

下载完整代码

参考:来自JCG合作伙伴的 Spring AOP实现活动记录模式   在一个罐子统治他们所有博客的亚历克斯·索托。

翻译自: https://www.javacodegeeks.com/2012/02/implementing-active-record-pattern-with.html

spring aop实践

spring aop实践_使用Spring AOP实现活动记录模式相关推荐

  1. 使用Spring AOP实现活动记录模式

    在班级设计中,我们应就每个班级的职责分配做出决定. 如果我们选择的不错,系统将更易于理解,维护和扩展. 几乎我们所有的项目都有一个持久层,即关系数据库,文档存储或仅XML文件. 通常,您将使用DAO模 ...

  2. python aop编程_学习笔记: AOP面向切面编程和C#多种实现

    AOP:面向切面编程   编程思想 OOP:一切皆对象,对象交互组成功能,功能叠加组成模块,模块叠加组成系统 类--砖头     系统--房子 类--细胞     系统--人 面向对象是非常适合做大型 ...

  3. spring mysql 注解_【Spring】SpringMVC之基于注解的实现SpringMVC+MySQL

    目录结构: contents structure [-] SpringMVC是什么 MVC的全称是Model View Controller,通过实现MVC框架可以很好的数据.视图.业务逻辑进行分离. ...

  4. spring生命周期_理解Spring应用上下文生命周期

    Spring应用上下文启动准备阶段 `BeanFactory`创建阶段 `BeanFactory`准备阶段 `BeanFactory`后置处理阶段 `AnnotationConfigServletWe ...

  5. spring boot测试_测试Spring Boot有条件的合理方式

    spring boot测试 如果您或多或少有经验的Spring Boot用户,那么很幸运,在某些时候您可能需要遇到必须有条件地注入特定bean或配置的情况 . 它的机制是很好理解的 ,但有时这样的测试 ...

  6. spring 事务 会话_测试Spring的“会话”范围

    spring 事务 会话 在基于Spring的Web应用程序中,bean的作用域可以是用户"会话". 从本质上讲,这意味着对会话范围Bean的状态更改仅在用户会话范围内可见. 本条 ...

  7. spring 工作流引擎_带Spring的简单工作流引擎

    spring 工作流引擎 几个月前,在处理一个公司项目时,我们需要开发REST服务,该服务用于根据客户端应用程序发送的数据发送电子邮件. 在开发此服务期间,我们决定创建简单的工作流引擎,该引擎将为发送 ...

  8. java spring 条件注解_【Spring】Spring高级话题-条件注解-@Condition

    进行本示例的演示,需要先配置好Maven和Spring哦. 见: [Spring]基于IntelliJ IDEA搭建Maven 分析 通过profile,我们可以获得不同的profile,我们可以获得 ...

  9. spring aop 注释_使用Spring AOP,自定义注释和反射为您的应用程序审核基础结构

    spring aop 注释 下一篇文章将演示如何使用Spring AOP和注释编写简单的审计. 审核机制将是干净,高效且易于维护的(和Kewwl!). 我将在用户管理系统上演示我的示例(假设您具有反射 ...

最新文章

  1. 用delphi创建服务程式
  2. pandas loc iloc(self index location 即按照行索引来获取数据)
  3. 【渝粤题库】国家开放大学2021春2246社会工作概论题目
  4. asp.net动态加载css
  5. Windows下C语言网络编程快速入门
  6. 使用java连接ftp服务器_Java如何连接到FTP服务器?
  7. 在JupyterNotebook中使用多个Python环境
  8. python脚本打包rpm_python程序打包rpm包
  9. python数据可视化雷达图程序_Python数据可视化之matplotlib
  10. Python2 圆满落幕,Python 继续辉煌! | 原力计划
  11. android nexus 6尺寸,谷歌Nexus 6详细配置曝光 原生Android大杀器
  12. Yii 多表关联relations
  13. 基于nodejs,tinypng的压缩图片工具
  14. mongo异常无法启动-处理方法
  15. Arduino框架下合宙ESP32C3 +1.8“TFT液晶屏通过TFT_eSPI库驱动显示
  16. oppo便签误删怎么办_oppo手机便签误删怎么办?oppo便签如何导入新手机
  17. 英语社交可以这样说吗?He's fat. 课本说可以!
  18. 使用docker和jenkins简单部署springboot项目
  19. 【操作系统】实验六 系统内存使用统计
  20. IT十年人生过客-十六-再见雍和宫

热门文章

  1. SpringCloud Netflix Ribbon
  2. 2小时学习Spring Boot 2019版本 代码一样推送至github上面去
  3. java常用代码_Java 中常用代码 (欢迎补充)
  4. 华为荣耀20计算机,华为云电脑将停止服务/荣耀新机保护壳曝光/小米新机渲染图曝光...
  5. azure 部署java_jClarity:在Azure上升级到Java
  6. idea 构建spring_以Spring方式构建企业Java应用程序
  7. wcg总决赛_关于总决赛
  8. hibernate查询缓存_在Hibernate中启用实体和查询缓存
  9. couchbase_具有Couchbase,Java EE和WildFly的CRUD Java应用程序
  10. activemq和jms_带有ActiveMQ和Maven的JMS Sender应用程序