Ich muss Zuordnungen für Klassen erstellen (wörtlich ein Map<Class<?>, String>
), die zur Laufzeit nicht variieren, und die Dinge entkoppelt zu halten ist eine Priorität. Da ich in einer Frühlings-Anwendung bin, dachte ich mir eine Anmerkung verwenden würde und ClassPathScanningCandidateComponentProvider
mehr oder weniger wie so:Spring Klassenpfad Komponente Scannen
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Mapping {
String value();
}
Und:
public class MappingLookUp {
private static final Map<Class<?>, String> MAPPING_LOOK_UP;
static {
Map<Class<?>, String> lookUp = new HashMap<>();
ClassPathScanningCandidateComponentProvider scanningCandidateComponentProvider = new ClassPathScanningCandidateComponentProvider(false);
scanningCandidateComponentProvider.addIncludeFilter(new AnnotationTypeFilter(Mapping.class));
for (BeanDefinition beanDefinition : scanningCandidateComponentProvider.findCandidateComponents("blah")) {
Class<?> clazz;
try {
clazz = Class.forName(beanDefinition.getBeanClassName());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
Mapping mapping = AnnotationUtils.getAnnotation(clazz, Mapping.class);
if (mapping == null) {
throw new IllegalStateException("This should never be null");
}
lookUp.put(clazz, mapping.value());
}
MAPPING_LOOK_UP = Collections.unmodifiableMap(lookUp);
}
public static String getMapping(Class<?> clazz) {
...
}
}
Obwohl ich das glaube funktionieren wird, das fühlt sich an wie:
- viel in einer statischen Initialisierung
- hacky Verwendung der Scan-Komponente Anbieter zu setzen, auch wenn es häufig ist reco für diesen Zweck empfohlen;
BeanDefinition
klingt so, als ob es eher Springbohnen als allgemeine Klassendefinitionen finden soll.
klar zu sein, sind die kommentierten Werte Klassen Daten - nicht feder Managed Beans - so ein BeanPostProcessor
Muster passt nicht, und in der Tat, deshalb fühlt es sich umständlich die Scan-Komponente-Anbieter zu verwenden, die, für mich, scheint für die Entdeckung von Spring Managed Beans gedacht.
Ist dies der richtige Weg, dieses Muster zu implementieren? Ist es eine ordnungsgemäße Anwendung des Anbieters? Gibt es eine praktikable Alternative, ohne andere Klassenpfad-Scan-Implementierungen einzubeziehen?
Eine Zuordnung von Klasse String, ziemlich seltsam scheint. Sie haben keine Einschränkung für die Klasse, wie eine Schnittstelle, die implementiert werden muss, und Strings sollten nur angezeigt werden. Könnten Sie den Anwendungsfall näher erläutern, könnte ich einen Fall von String zu Class sehen, aber nicht umgekehrt. - Und meine Augen schmerzen, wenn Sie statische Initialisierer verwenden, besonders wenn Sie mit Spring arbeiten ;-) –
Dies sind verschiedene Objekttypen, die effektiv für ein cross-cutting Audit-System markiert werden müssen. Ich könnte eine Schnittstelle mit einer Methode erzwingen, die das Tag zurückgibt, aber da dieser Wert zur Laufzeit nie variiert und für keine der implementierenden Klassen wichtig ist, halte ich eine Annotation für besser geeignet. Es sind sehr viele Metadaten. – jwilner
Sie haben also eine Instanz der Klasse und rufen dann MappingLookUp auf. getMapping (instance.getClass()) ', um die Prüfzeichenfolge zu erhalten? –