spring aop示例

This is a very simple Spring ORM example that shows you how to configure an application with Spring that uses

这是一个非常简单的Spring ORM示例,向您展示了如何使用具有以下功能的Spring配置应用程序:

  • Dependency Injection (@Autowired annotation),依赖注入(@Autowired注释),
  • JPA EntityManager (provided by Hibernate),JPA EntityManager(由Hibernate提供),
  • Transactional methods (AOP configured).事务方法(已配置AOP)。

Spring ORM示例与AOP事务 (Spring ORM Example with AOP Transactions)

To configure the transactional methods we do not use @Transactional annotations now because we use aspect oriented approach now (eg.: we can say all methods in the service package starting with “get” is a read-only transactional method). We use in-memory database for this example to simplify, so no need for any database setup. This is a standalone application example.

为了配置事务方法,我们现在不使用 @Transactional注释,因为我们现在使用面向方面的方法(例如:我们可以说服务包中以“ get”开头的所有方法都是只读事务方法)。 在本示例中,我们使用内存数据库进行简化,因此无需任何数据库设置。 这是一个独立的应用程序示例。

(For @Transactional annotated approach please check this tutorial:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction)

(对于@Transactional注释方法,请查看此教程:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction )

The project structure:

项目结构:

We go through these files one by one and explain them:

我们逐一浏览这些文件并解释它们:

1. Maven依赖 (1. Maven dependencies)

We will first look into our pom.xml file for all the required dependencies and their versions. We have used Spring 4, and Hibernate 4 in this example.

我们将首先在pom.xml文件中查找所有必需的依赖项及其版本。 在此示例中,我们使用了Spring 4和Hibernate 4。

<project xmlns="https://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>hu.daniel.hari.learn.spring</groupId><artifactId>Tutorial-SpringORMwithTX-AOP</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><!-- Generic properties --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.7</java.version><!-- SPRING & HIBERNATE / JPA --><spring.version>4.0.0.RELEASE</spring.version><hibernate.version>4.1.9.Final</hibernate.version></properties><dependencies><!-- LOG --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version></dependency><!-- Spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>${spring.version}</version></dependency><!-- AspectJ (required spring-aop dependency) --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.5</version></dependency><!-- JPA Implementation (Hibernate)--><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>${hibernate.version}</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency><!-- IN MEMORY Database and JDBC Driver --><dependency><groupId>hsqldb</groupId><artifactId>hsqldb</artifactId><version>1.8.0.7</version></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.1</version><configuration><source>${java.version}</source><target>${java.version}</target></configuration></plugin></plugins></build></project>
  • We need spring-context and spring-orm as Spring dependencies.我们需要spring-contextspring-orm作为Spring依赖项。
  • spring-aop also comes with spring-context as it’s dependent library, so no need to add it.spring-aop还带有spring-context,因为它是依赖库,因此无需添加它。
  • aspectjweaver is spring-aop’s dependency, but we have to add it since it is not defined explicitly for spring-aop.Aspectjweaver是spring-aop的依赖项,但由于没有为spring-aop明确定义,因此我们必须添加它。
  • We use hibernate-entitymanager for using Hibernate as a JPA Vendor. hibernate-entitymanager is dependent to hibernate-core this why we don’t have to put hibernate-core in pom.xml explicitly.我们使用hibernate-entitymanager将Hibernate用作JPA供应商。 hibernate-entitymanager依赖于hibernate-core,这就是为什么我们不必将hibernate-core显式放入pom.xml的原因。
  • We need also a JDBC driver as a dependency for DB access that Hibernate uses. In this example we used hsqldb that contains the JDBC driver, and a working in memory db also for this example. (If you want to use external database, you have to change this to that db’s JDBC driver, fe: PostgreSQL, or mysql-connector-java maven dependency.)我们还需要一个JDBC驱动程序作为Hibernate使用的数据库访问的依赖项。 在此示例中,我们使用了包含JDBC驱动程序的hsqldb以及该示例中的在内存中工作的数据库。 (如果要使用外部数据库,则必须将其更改为该数据库的JDBC驱动程序,例如PostgreSQL或mysql-connector-java maven依赖项。)

2.型号类别 (2. Model Class)

We can use standard JPA annotations for mapping in our model because Hibernate provides JPA implementation.

因为Hibernate提供了JPA实现,所以我们可以在模型中使用标准的JPA批注进行映射。

package hu.daniel.hari.learn.spring.orm.model;import javax.persistence.Entity;
import javax.persistence.Id;@Entity
public class Product {@Idprivate Integer id;private String name;public Product() {//Default constructor needed for JPA.}public Product(Integer id, String name) {this.id = id;this.name = name;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Product [id=" + id + ", name=" + name + "]";}
}

We use @Entity and @Id JPA annotations to qualify our POJO as an Entity and defining it’s primary key.

我们使用@Entity@Id JPA批注将POJO限定为实体并定义其主键。

3.道课 (3. Dao Class)

We create a very simple DAO class, that have persist and findALL methods.

我们创建一个非常简单的DAO类,它具有persist和findALL方法。

package hu.daniel.hari.learn.spring.orm.dao;import hu.daniel.hari.learn.spring.orm.model.Product;import java.util.List;import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;import org.springframework.stereotype.Component;@Component
public class ProductDao {@PersistenceContextprivate EntityManager em;public void persist(Product product) {System.out.println("persist:"+product);em.persist(product);}public List<Product> findAll() {return em.createQuery("SELECT p FROM Product p").getResultList();}
}
  • @Component is Spring annotation that tell the Spring container that we can use this class through Spring IoC (Dependency Injection).@Component是Spring注释,它告诉Spring容器我们可以通过Spring IoC(依赖注入)使用此类。
  • We use JPA’s @PersistenceContext annotation that indicate dependency injection to an EntityManager. Spring injects a proper instance of EntityManager according to the spring.xml configuration.我们使用JPA的@PersistenceContext批注,该批注指示对EntityManager的依赖项注入。 Spring根据spring.xml配置注入适当的EntityManager实例。

4.服务等级 (4. Service Class)

Our simple service class has 2 write and 1 read methods: add, addAll, and listAll.

我们的简单服务类具有2种写入和1种读取方法:add,addAll和listAll。

package hu.daniel.hari.learn.spring.orm.service;import hu.daniel.hari.learn.spring.orm.dao.ProductDao;
import hu.daniel.hari.learn.spring.orm.model.Product;import java.util.Collection;
import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class ProductService {@Autowiredprivate ProductDao productDao;public void add(Product product) {productDao.persist(product);}public void addAll(Collection<Product> products) {for (Product product : products) {productDao.persist(product);}}public List<Product> listAll() {return productDao.findAll();}
}

Please note that

请注意

  • there are no @Transactional annotations before the methods, but we want these methods to be transactional. The reason is that we use AOP approach to configure which methods are transactional that will be configured in spring.xml below.方法之前没有 @Transactional批注,但我们希望这些方法具有事务性。 原因是我们使用AOP方法来配置哪些方法是事务性的,这些方法将在下面的spring.xml中进行配置。
  • We use Spring’s @Autowired annotation to have ProductDao component be dependency injected.我们使用Spring的@Autowired批注将ProductDao组件注入依赖项。

5. Spring配置XML (5. Spring configuration XML)

Now we have ready with every working classes needed in our mini application. Let’s create Spring’s configuration file:

现在,我们已经准备好迷你应用程序中所需的每个工作类。 让我们创建Spring的配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans" xmlns:p="https://www.springframework.org/schema/p"xmlns:context="https://www.springframework.org/schema/context" xmlns:tx="https://www.springframework.org/schema/tx" xmlns:aop="https://www.springframework.org/schema/aop"xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttps://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context-3.0.xsdhttps://www.springframework.org/schema/txhttps://www.springframework.org/schema/tx/spring-tx.xsdhttps://www.springframework.org/schema/aophttps://www.springframework.org/schema/aop/spring-aop.xsd"><!-- Scans the classpath for annotated components that will be auto-registered as Spring beans --><context:component-scan base-package="hu.daniel.hari.learn.spring" /><!-- Activates various annotations to be detected in bean classes e.g: @Autowired --><context:annotation-config /><!-- JPA --><!-- Datasource, that is currently hsqldb (in-memory database). --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="org.hsqldb.jdbcDriver" /><property name="url" value="jdbc:hsqldb:mem://productDb" /><property name="username" value="sa" /><property name="password" value="" /></bean><!-- EntityManagerFactory --><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:packagesToScan="hu.daniel.hari.learn.spring.orm.model" p:dataSource-ref="dataSource"><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="generateDdl" value="true" /><property name="showSql" value="true" /></bean></property></bean><!-- AOP Configuration for selecting transactional methods --><!-- the transactional advice (what 'happens'; see the <aop:advisor/> ) --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!-- all methods starting with 'list' or 'get' are read-only --><tx:method name="list*" read-only="true"/><tx:method name="get*" read-only="true"/><!-- for other methods use the default transaction settings --><tx:method name="*" /></tx:attributes></tx:advice><!-- ensure that the above transactional advice runs for any executionof a method in the service package --><aop:config><aop:pointcut id="serviceMethods" expression="execution(* hu.daniel.hari.learn.spring.orm.service.*.*(..))" /><aop:advisor pointcut-ref="serviceMethods" advice-ref="txAdvice" /></aop:config><!-- TransactionManager --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory" /></bean></beans>
  • First we tell spring that we want to use classpath scanning for Spring components (Services, DAOs, etc…) rather than unconviniently defining them one by one in this xml, and also we enable Spring annotation detection.首先,我们告诉spring我们要对Spring组件(服务,DAO等)使用类路径扫描,而不是在此xml中不方便地一个接一个地定义它们,并且还要启用Spring注释检测。
  • Adding the datasource, that is currently hsqldb (in-memory database).添加数据源,当前为hsqldb(内存数据库)。
  • We set up a JPA EntityManagerFactory that will used by the application to obtain an EntityManager. Spring supports 3 different ways to do this (see the reference below for details), and we use LocalContainerEntityManagerFactoryBean for full JPA capabilities.
    We set it’s attributes as:

    • packagesToScan attribute that points to our models’ package. (no need for persistence.xml)
    • datasource (defined above)
    • jpaVendorAdapter as Hibernate (also setting some hibernate property)

    我们设置了一个JPA EntityManagerFactory,应用程序将使用它来获取EntityManager。 Spring支持3种不同的方法来执行此操作(有关详细信息,请参见下面的参考),我们使用LocalContainerEntityManagerFactoryBean来获得完整的JPA功能。
    我们将其属性设置为:

    • packagesToScan属性,它指向我们模型的包。 (不需要persistence.xml)
    • 数据源(上面定义)
    • jpaVendorAdapter作为Hibernate(还设置了一些hibernate属性)
  • We configure the Spring-AOP behavior the following way: We want all methods in the service package transactional, and for methods starting with “get*” or “list*”, we want them to be read-only transactional. This simple.我们通过以下方式配置Spring-AOP行为: 我们希望服务包中的所有方法都是事务性的,对于以“ get *”或“ list *”开头的方法,我们希望它们是只读的transactional 。 这个简单。
  • We create Spring’s PlatformTransactionManager instance as a JpaTransactionManager. (This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access.)我们将Spring的PlatformTransactionManager实例创建为JpaTransactionManager。 (此事务管理器适用于使用单个JPA EntityManagerFactory进行事务数据访问的应用程序。)

6. Spring ORM示例测试类 (6. Spring ORM Example Test Class)

Our setup is ready, so let’s write a testing class for our application.

我们的设置已经准备就绪,所以让我们为应用程序编写一个测试类。

package hu.daniel.hari.learn.spring.orm.main;import hu.daniel.hari.learn.spring.orm.model.Product;
import hu.daniel.hari.learn.spring.orm.service.ProductService;import java.util.Arrays;import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;/** * Simple tester for a Spring application that uses JPA * with AOP based Transactions. **/
public class SpringOrmMain {public static void main(String[] args) {//Create Spring application contextClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/spring.xml");//Get service from context. (service's dependency (ProductDAO) is autowired in ProductService)ProductService productService = ctx.getBean(ProductService.class);//Do some data operationproductService.add(new Product(1, "Television"));productService.add(new Product(2, "Phone"));System.out.println("listAll: " + productService.listAll());//Test transaction rollback (for duplicated key)try {productService.addAll(Arrays.asList(new Product(3, "Peach"), new Product(4, "Strawberry"), new Product(1, "Melone")));} catch (DataAccessException dataAccessException) {//Do nothing here, we just test rollback}//Test element list after rollback (same two element, 3 more hasn't been added.)System.out.println("listAll: " + productService.listAll());ctx.close();}
}

You can see how simple we can start the Spring container from a main method, and getting our first dependency injected entry point, the service class instance. ProductDao class reference injected to the ProductService class after the context initialized.

您会看到我们可以简单地从main方法启动Spring容器,并获得我们的第一个依赖项注入入口点,即服务类实例。 在上下文初始化之后,将ProductDao类引用注入到ProductService类。

After we got ProducService instance, we can test it’s methods, all method call will be transactioned due to Spring’s proxy mechanism. We also test rollback in this example.

获得ProducService实例后,我们可以测试其方法,由于Spring的代理机制,所有方法调用都将被事务处理。 在此示例中,我们还将测试回滚。

If you run, you get below log:

如果运行,将获得以下日志:

Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: select product0_.id as id0_, product0_.name as name0_ from Product product0_
listAll: [Product [id=1, name=Bulb], Product [id=2, name=Dijone mustard]]
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: insert into Product (name, id) values (?, ?)
Hibernate: select product0_.id as id0_, product0_.name as name0_ from Product product0_
listAll: [Product [id=1, name=Bulb], Product [id=2, name=Dijone mustard]]

Note that the second transaction rolled back, this why product list didn’t changed.

请注意,第二笔交易回滚了,这就是为什么产品列表未更改的原因。

You can see that we made transactional methods without specifying them one by one with @Transactional annotations, as we configured it in AOP approach.

您可以看到,我们制作事务方法时并没有使用@Transactional批注一一指定它们 ,就像我们在AOP方法中配置它一样。

If you use log4j.properties file from attached source, you can see what’s going on under the hood.

如果使用附件中的log4j.properties文件,则可以查看实际情况。

References:
Object Relational Mapping (ORM) Data Access
Aspect Oriented Programming with Spring

参考文献:
对象关系映射(ORM)数据访问
Spring面向方面的编程

(For @Transactional annotated approach please check this tutorial:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction)

(对于@Transactional注释方法,请查看此教程:
https://www.journaldev.com/7655/spring-orm-example-jpa-hibernate-transaction )

You can download the final maven project source from below link and play around with it to learn more.

您可以从下面的链接下载最终的maven项目源,并尝试使用它来了解更多信息。

Download Spring ORM with Transaction AOP Project下载带有事务AOP项目的Spring ORM

翻译自: https://www.journaldev.com/7772/spring-orm-example-aop-transactions

spring aop示例

spring aop示例_具有AOP事务管理的Spring ORM示例相关推荐

  1. spring框架学习 - Data Access之 事务管理 - 声明式事务管理

    接上一篇博客:https://blog.csdn.net/qq_43605444/article/details/122085016?spm=1001.2014.3001.5502 4.声明式事务管理 ...

  2. spring事物配置,声明式事务管理和基于@Transactional注解的使用

    事物管理对于企业应用来说是至关重要的,好使出现异常情况,它也可以保证数据的一致性. spring支持编程式事务管理和声明式事务管理两种方式. 编程式事务管理使用TransactionTemplate或 ...

  3. Spring详解(八)------事务管理

    目录 1.事务介绍 2.事务的四个特性(ACID) 3.Spring 事务管理的核心接口 4. PlatformTransactionManager  事务管理器 5.TransactionStatu ...

  4. Spring+Mybatis+MySql+Maven 简单的事务管理案例

    利用Maven来管理项目中的JAR包,同时使用Spring在业务处理层进行事务管理.数据库使用MySq,数据处理层使用Spring和Mybatis结合. 本案例代码主要结构如图: 1.数据库脚本 -- ...

  5. Day3-Spring的事务管理、Spring框架的JDBC模板

    今天内容 1. Spring框架的AOP之注解的方式2. Spring框架的JDBC模板3. Spring框架的事务管理 案例一:使用Spring框架的AOP技术对DAO层的功能进行增强 案例一:使用 ...

  6. Spring事务管理-》Spring事务管理(annotation)

    5.6 使用@Transactional 除了使用XML类型的事务管理,同时Spring也提供了Annotation类型的事务管理.如下所示: 一:Spring事务管理 =============== ...

  7. spring实战学习(六)事务管理

    什么是事务? 在软件领域,我们将一组要么全部执行要么全不执行的操作叫做事物. 事务的四个特性(ACID) 原子性(atomicity):原子性确保了事物中的操作像原子操作一样要就全部执行或全不执行,如 ...

  8. Spring笔记(9):事务管理ACID

    一.事务管理 一个数据库事务是一个被视为单一的工作单元操作序列. 事务管理有四个原则,被成为ACID: Atomicity 原子性-- 事务作为独立单元进行操作,整个序列是一体的,操作全都成功或失败. ...

  9. Spring整合JMS(四)——事务管理

    2019独角兽企业重金招聘Python工程师标准>>> Spring整合JMS(四)--事务管理 博客分类: Spring Jms SpringJMS事务sessionTransac ...

  10. mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚

    mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚 参考文章: (1)mysql事务管理及spring声明式事务中主动异常抛出使数据库回滚 (2)https://www.cnblog ...

最新文章

  1. python安装位置是固定的吗_pip指定python位置安装软件包的方法
  2. Cocos2d-x 生成真正的随机数
  3. 我的计算机怎么打不开怎么办理,我的电脑打不开,怎么办【解决方法】
  4. 狄利克雷卷积_一些狄利克雷卷积性质的证明
  5. 网址导航html5源码图标版,最新仿hao123网址导航(晓风网址导航系统) v4.2
  6. IT团队如何赢得尊重?
  7. BestCoder22 1003.NPY and shot 解题报告
  8. springboot中使用websocket_Spring Boot中Lombok使用
  9. 数字图像处理(三)——频域滤波
  10. 【Android Studio安装部署系列】三十一、从Android studio3.0.0升级到Android studio3.0.1
  11. linux源码中的核心数据结构
  12. 实时全局光照Screen Space Reflection (SSR)
  13. Unity3d学习之路-简单打飞碟小游戏
  14. Stata: 正则表达式和文本分析
  15. 软件评测师题库--操作系统基础知识
  16. upupoo php,UPUPOO动态桌面下载
  17. python xlutils模块安装_python接口测试,第三方包xlrd和xlutils,怎么安装
  18. IMU(Inertial measurement unit)
  19. 古筝d调变降e调怎么办_古筝怎么从D调转成E调
  20. ALSA-ASOC音频驱动框架简述

热门文章

  1. TD8.0管理员工具
  2. [转载] python异常和错误有什么区别_python的错误和异常
  3. [转载] java 捕获异常还是抛出异常
  4. [转载] 浅析Java OutOfMemoryError
  5. 接口jdk1.8与jdk1.9新特性
  6. _itemmod_description
  7. 【题解】SDOI2018战略游戏
  8. centos 设置时间为北京时间
  9. MYSQL:RELPACE用法
  10. 优化MyBatis配置文件中的配置