1. Overview
1.概述
In this article, we will be looking at the JaVers library.
在这篇文章中,我们将看一下JaVers库。
This library helps programmers examine and detect changes in the states of simple Java objects. When we use mutable objects in our code, every object can potentially be modified in various places in the application; JaVers would help us discover and audit these changes.
这个库帮助程序员检查和检测简单Java对象的状态变化。当我们在代码中使用可变型对象时,每个对象都有可能在应用程序的不同地方被修改;JaVers将帮助我们发现和审计这些变化。
2. Maven Dependency
2.Maven的依赖性
To get started let us add the javers-core Maven dependency to our pom.xml:
为了开始工作,让我们把javers-core的Maven依赖性添加到pom.xml。
<dependency>
<groupId>org.javers</groupId>
<artifactId>javers-core</artifactId>
<version>3.1.0</version>
</dependency>
We can find the latest version over on Maven Central.
我们可以在Maven Central上找到最新版本。
3. Detecting POJO State Changes
3.检测POJO的状态变化
Let’s start with a simple Person class:
让我们从一个简单的Person类开始。
public class Person {
private Integer id;
private String name;
// standard getters/constructors
}
Suppose that we created a Person object in one part of our application, and in some other part of the codebase, the name of the person with the same id field was changed. We want to compare them to find out what kind of changes happened to the person object.
假设我们在应用程序的一个部分创建了一个Person对象,而在代码库的另一个部分,具有相同id字段的人的名字被改变。我们想通过比较来找出这个人的对象发生了什么样的变化。
We can compare those two objects using the compare() method from the JaVers class:
我们可以使用compare()方法比较这两个对象,该方法来自JaVers类。
@Test
public void givenPersonObject_whenApplyModificationOnIt_thenShouldDetectChange() {
// given
Javers javers = JaversBuilder.javers().build();
Person person = new Person(1, "Michael Program");
Person personAfterModification = new Person(1, "Michael Java");
// when
Diff diff = javers.compare(person, personAfterModification);
// then
ValueChange change = diff.getChangesByType(ValueChange.class).get(0);
assertThat(diff.getChanges()).hasSize(1);
assertThat(change.getPropertyName()).isEqualTo("name");
assertThat(change.getLeft()).isEqualTo("Michael Program");
assertThat(change.getRight()).isEqualTo("Michael Java");
}
4. Detecting State Change of List of Objects
4.检测对象列表的状态变化
If we’re working with collections of objects, we similarly need to examine state changes by looking at the each element in the collection. Sometimes, we want to add or remove the particular object from the list, altering its state.
如果我们正在处理对象的集合,我们同样需要通过查看集合中的每个元素来检查状态变化。有时,我们想从列表中添加或删除特定对象,改变其状态。
Let’s have a look at an example; say we have a list of objects, and we remove one object from that list.
让我们看一个例子;比如我们有一个对象的列表,我们从这个列表中删除一个对象。
That change can be undesirable for some reason, and we want to audit changes that occurred in this list. JaVers allows us to do it by using a compareCollections() method:
由于某些原因,这种变化可能是不可取的,我们想审计这个列表中发生的变化。JaVers允许我们通过使用compareCollections()方法来做到这一点。
@Test
public void givenListOfPersons_whenCompare_ThenShouldDetectChanges() {
// given
Javers javers = JaversBuilder.javers().build();
Person personThatWillBeRemoved = new Person(2, "Thomas Link");
List<Person> oldList =
Lists.asList(new Person(1, "Michael Program"), personThatWillBeRemoved);
List<Person> newList =
Lists.asList(new Person(1, "Michael Not Program"));
// when
Diff diff = javers.compareCollections(oldList, newList, Person.class);
// then
assertThat(diff.getChanges()).hasSize(3);
ValueChange valueChange =
diff.getChangesByType(ValueChange.class).get(0);
assertThat(valueChange.getPropertyName()).isEqualTo("name");
assertThat(valueChange.getLeft()).isEqualTo("Michael Program");
assertThat(valueChange.getRight()).isEqualTo("Michael Not Program");
ObjectRemoved objectRemoved = diff.getChangesByType(ObjectRemoved.class).get(0);
assertThat(
objectRemoved.getAffectedObject().get().equals(personThatWillBeRemoved))
.isTrue();
ListChange listChange = diff.getChangesByType(ListChange.class).get(0);
assertThat(listChange.getValueRemovedChanges().size()).isEqualTo(1);
}
5. Comparing Object Graphs
5.比较对象图
In real word applications, we often deal with the object graphs. Let’s say that we have a PersonWithAddress class that has a list of the Address objects and we are adding a new address for the given person.
在实际的文字应用中,我们经常处理对象图。假设我们有一个PersonWithAddress类,它有一个Address对象的列表,我们要为给定的人添加一个新地址。
We can easily find the type of change that has occurred:
我们可以很容易地找到已经发生的变化类型。
@Test
public void givenListOfPerson_whenPersonHasNewAddress_thenDetectThatChange() {
// given
Javers javers = JaversBuilder.javers().build();
PersonWithAddress person =
new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England")));
PersonWithAddress personWithNewAddress =
new PersonWithAddress(1, "Tom",
Arrays.asList(new Address("England"), new Address("USA")));
// when
Diff diff = javers.compare(person, personWithNewAddress);
List objectsByChangeType = diff.getObjectsByChangeType(NewObject.class);
// then
assertThat(objectsByChangeType).hasSize(1);
assertThat(objectsByChangeType.get(0).equals(new Address("USA")));
}
Similarly, removing an address will be detected:
同样,删除一个地址也会被发现。
@Test
public void givenListOfPerson_whenPersonRemovedAddress_thenDetectThatChange() {
// given
Javers javers = JaversBuilder.javers().build();
PersonWithAddress person =
new PersonWithAddress(1, "Tom", Arrays.asList(new Address("England")));
PersonWithAddress personWithNewAddress =
new PersonWithAddress(1, "Tom", Collections.emptyList());
// when
Diff diff = javers.compare(person, personWithNewAddress);
List objectsByChangeType = diff.getObjectsByChangeType(ObjectRemoved.class);
// then
assertThat(objectsByChangeType).hasSize(1);
assertThat(objectsByChangeType.get(0).equals(new Address("England")));
}
6. Conclusion
6.结论
In this quick article, we used the JaVers library, a useful library that gives us APIs for detecting state changes in our objects. Not only it can detect the change in a simple POJO object, but also it can detect more complex shifts in the collections of objects, or even object graphs.
在这篇短文中,我们使用了JaVers库,这是一个有用的库,它为我们提供了检测对象中状态变化的API。它不仅可以检测简单的POJO对象的变化,而且还可以检测对象集合中更复杂的转变,甚至是对象图。
As always, the code is available over on GitHub.
像往常一样,代码可在GitHub上获得。