«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 позволяет нам получать доступ к этим значениям и изменять их с помощью одного вызова метода.