«1. Обзор

Apache Commons BeansUtils содержит все инструменты, необходимые для работы с Java-бинами.

Проще говоря, компонент — это простые классы Java, содержащие поля, геттеры/сеттеры и конструктор без аргументов.

Java предоставляет возможности рефлексии и самоанализа для идентификации методов получения-установки и их динамического вызова. Однако эти API могут быть сложными для изучения и могут потребовать от разработчиков написания стандартного кода для выполнения простейших операций.

2. Зависимости Maven

Вот зависимость Maven, которую необходимо включить в файл POM перед ее использованием:

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.3</version>
</dependency>

Новейшую версию можно найти здесь.

3. Создание Java Bean

Давайте создадим два класса bean-компонентов Course и Student с типичными методами получения и установки.

public class Course {
    private String name;
    private List<String> codes;
    private Map<String, Student> enrolledStudent = new HashMap<>();

    //  standard getters/setters
}

public class Student {
    private String name;

    //  standard getters/setters
}

У нас есть класс Course с названием курса, кодами курсов и несколькими зачисленными студентами. Зачисленные студенты идентифицируются по уникальному идентификатору зачисления. Класс курса поддерживает зарегистрированных студентов в объекте карты, где идентификатор зачисления является ключом, а объект студента будет значением.

4. Доступ к свойствам

Свойства компонента можно разделить на три категории.

4.1. Простое свойство

Свойства с одним значением также называются простыми или скалярными.

Их значение может быть примитивным (например, int, float) или объектом сложного типа. BeanUtils имеет класс PropertyUtils, который позволяет нам изменять простые свойства в Java Bean.

Course course = new Course();
String name = "Computer Science";
List<String> codes = Arrays.asList("CS", "CS01");

PropertyUtils.setSimpleProperty(course, "name", name);
PropertyUtils.setSimpleProperty(course, "codes", codes);

Вот пример кода для установки свойств:

4.2. Индексированное свойство

Индексированные свойства имеют коллекцию в качестве значения, к которому можно получить индивидуальный доступ с помощью индексного номера. Как расширение JavaBean, BeanUtils также считает значения типа java.util.List индексированными.

Мы можем изменить отдельное значение индексированного свойства, используя метод setIndexedProperty класса PropertyUtils.

PropertyUtils.setIndexedProperty(course, "codes[1]", "CS02");

Вот пример кода, изменяющего индексированное свойство:

4.3. Сопоставленное свойство

Любое свойство, имеющее java.util.Map в качестве базового типа, называется сопоставленным свойством. BeanUtils позволяет нам обновлять отдельное значение на карте с помощью ключа со строковым значением.

Student student = new Student();
String studentName = "Joe";
student.setName(studentName);

PropertyUtils.setMappedProperty(course, "enrolledStudent(ST-1)", student);

Вот пример кода для изменения значения сопоставленного свойства:

5. Доступ к вложенным свойствам

Если значение свойства является объектом, и нам нужно получить доступ к значению свойства внутри этого объекта â – это будет доступ к вложенному свойству. PropertyUtils также позволяет нам получать доступ к вложенным свойствам и изменять их.

String name = course.getEnrolledStudent("ST-1").getName();

Предположим, мы хотим получить доступ к свойству name класса Student через объект Course. Мы могли бы написать:

Student student = new Student();
String studentName = "Joe";
student.setName(studentName);

String nameValue 
  = (String) PropertyUtils.getNestedProperty(
  course, "enrolledStudent(ST-1).name");

Мы можем получить доступ к значениям вложенных свойств, используя getNestedProperty, и изменить вложенное свойство, используя методы setNestedProperty в PropertyUtils. Вот код:

6. Копирование свойств компонента

Копирование свойств одного объекта в другой объект часто утомительно и чревато ошибками для разработчиков. Класс BeanUtils предоставляет метод copyProperties, который копирует свойства исходного объекта в целевой объект, где имя свойства одинаково в обоих объектах.

public class CourseEntity {
    private String name;
    private List<String> codes;
    private Map<String, Student> students = new HashMap<>();

    //  standard getters/setters
}

Давайте создадим еще один класс bean-компонента, такой как Course, который мы создали выше, с теми же свойствами, за исключением того, что у него не будет свойства enrolledStudent, вместо этого свойство будет иметь имя student. Назовем этот класс CourseEntity. Класс будет выглядеть так:

Course course = new Course();
course.setName("Computer Science");
course.setCodes(Arrays.asList("CS"));
course.setEnrolledStudent("ST-1", new Student());

CourseEntity courseEntity = new CourseEntity();
BeanUtils.copyProperties(courseEntity, course);

Теперь мы скопируем свойства объекта Course в объект CourseEntity:

Помните, что при этом будут скопированы только свойства с одинаковыми именами. Поэтому он не будет копировать свойство enrolledStudent в классе Course, поскольку в классе CourseEntity нет свойства с таким же именем.

7. Заключение

В этой быстрой статье мы рассмотрели служебные классы, предоставляемые BeanUtils. Мы также рассмотрели различные типы свойств и то, как мы можем получить доступ к их значениям и изменить их.

Наконец, мы рассмотрели доступ к значениям вложенных свойств и копирование свойств одного объекта в другой объект.

«Конечно, возможности отражения и самоанализа в Java SDK также позволяют нам получать доступ к свойствам динамически, но это может быть сложно изучить и потребовать некоторого шаблонного кода. BeanUtils позволяет нам получать доступ к этим значениям и изменять их с помощью одного вызова метода.