EN · DE · RU · FR · ES

#1875 : BeanHelper.java

projectforge-common/src/main/java/org/projectforge/common/BeanHelper.java Classe utilitaire — package org.projectforge.common, projectforge-common/src/main/java/org/projectforge/common/BeanHelper.java 678 lignes · 481 code · 150 commentaires · 47 vides
Utilitaire complet d'introspection et de réflexion JavaBean. Infrastructure centrale pour la couche d'intégration ORM/Wicket de ProjectForge — fournit la résolution de noms de propriétés à partir des méthodes getter/setter, la recherche de méthodes getter/setter avec mise en cache extensive (cinq caches internes pour la performance), la découverte d'annotations de champs, l'accès aux propriétés imbriquées/indexées, la copie de propriétés avec détection des différences, et l'instanciation d'objets par réflexion. Largement utilisé dans tous les modules ProjectForge pour le tri des listes Wicket, la liaison de formulaires et la conversion DO vers DTO.

Architecture

Imports

Architecture de mise en cache interne

BeanHelper utilise cinq caches synchronisés statiques pour éviter les appels de réflexion répétés, qui sont coûteux en Java. Ceci est critique pour les pages de listes Wicket où BeanHelper est appelé pour chaque cellule d'un tableau de données triable.

CacheCléValeurBénéfice
declaredFieldsCacheClassField[]Évite de re-parcourir la hiérarchie de classes pour les champs
declaredMethodsCacheClassMethod[]Évite de re-parcourir la hiérarchie de classes pour les méthodes
declaredFieldAnnotationsCache"classe:nomchamp"Annotation[]Évite de re-résoudre les champs annotés (critique pour le tri des colonnes Wicket)
getterMethodsCache"classe:nomchamp"MethodÉvite de re-chercher les méthodes getter
declaredGetterMethodsCacheStringMethod[]Déclaré mais semble inutilisé dans le code fourni — peut être peuplé ailleurs

Opérations clés

Résolution de noms de propriétés

Accès aux annotations

getDeclaredAnnotations(Class, nomchamp) prend en charge les chemins de propriétés imbriqués (séparés par des points, ex. "adresse.ville.nom") en parcourant la chaîne de champs par réflexion pour trouver les annotations du champ terminal. Ceci est essentiel pour les tableaux de données Wicket qui affichent les propriétés d'objets imbriqués avec des colonnes triables.

Accès aux propriétés (imbriquées + indexées)

Copie de propriétés (copyProperties)

Copie les propriétés spécifiées de l'objet source vers l'objet de destination, retournant true si une propriété a effectivement changé. Prend en charge :

Utilitaires de réflexion

Fonctionnalité de mode test

Le drapeau TEST_MODE (contrôlé par enterTestMode()/exitTestMode()) supprime la journalisation des erreurs pendant l'exécution des tests. Cela permet aux tests de tenter des opérations de réflexion qui sont censées échouer sans polluer les journaux de test avec des traces de pile. Les méthodes logInstantiationException() respectent ce drapeau.

Décisions de conception

  1. Mise en cache agressive : Cinq caches existent car la réflexion est lente et BeanHelper est appelé sur des chemins chauds (rendu et tri des tableaux de données Wicket)
  2. Filtrage des méthodes pont : determineGetter() ignore les méthodes pont (méthodes synthétiques créées par le compilateur pour l'effacement de type générique) pour retourner la méthode réellement implémentée
  3. Parcours sûr pour les nulls : getNestedProperty() retourne null à tout point de la chaîne où une valeur intermédiaire est null, plutôt que de lever une NPE
  4. Accessibilité des constructeurs : newInstance() appelle constructor.setAccessible(true) pour instancier des classes avec des constructeurs privés
  5. Aucune bibliothèque de beans externe : Bien qu'il dépende de commons-beanutils dans la construction Gradle, BeanHelper implémente sa propre résolution de propriétés plutôt que d'utiliser Apache BeanUtils directement — probablement pour le contrôle des performances et la mise en cache
L'assistant isEqualList() (package-privé) effectue une comparaison élément par élément en utilisant des itérateurs, pas equals(). Cela signifie que l'égalité des collections est basée sur l'identité/l'égalité des éléments aux positions correspondantes, et non sur l'égalité d'ensemble — deux listes avec les mêmes éléments dans un ordre différent ne sont pas égales.

Historique Git

868d6abb7 2025 -> 2026
63081666f En-têtes des fichiers source : 2024 -> 2025.
a73905c14 Correction de fautes de frappe dans les répertoires projectforge*/ Trouvé via codespell
694987647 Migration en cours... (tous les tests de tous les packages : OK).
ae50b2522 BeanHelper.getProperty supporte désormais les propriétés imbriquées en utilisant simplement new PropertyUtils.
b6092df09 Copyright 2023 -> 2024
ab45d51fa Copyright 2001-2022 -> 2001-2023.
0203e3261 AbstractListPage : requêtes longues : le changement d'ordre de tri affiche la liste des résultats sans bouton de recherche. BeanHelper : beaucoup de caches pour un tri plus rapide dans les listes de résultats Wicket.