Implementieren Sie benutzerdefinierte Anmerkungen im Frühjahr


gdiquest

Ich möchte eine Annotation implementieren, die Klassen (keine Instanzen von Klassen) bei einer Factory registriert, sobald die Anwendung gestartet wird. Ich verwende Spring Framework 4.2.7.

Stellen Sie sich ein System mit einem Dashboard und mehreren Widgets vor. Das Dashboard verfügt über eine Konfigurationsdatei, die eine Liste von Widgets enthält, die für den aktuellen Benutzer angezeigt werden sollen. Wenn es angezeigt wird, liest es die Konfiguration und erstellt die Widgets. Die Widgets erhalten zusätzliche Parameter aus der Konfiguration.

Hier ist ein Code, der dies veranschaulicht:

public class TestDashboard implements Dashboard {
    public void dashboardPreDisplay() {
        List<String> widgets = getWidgetList(/* current user in session */);
        for (String widgetId : widgets) {
            // create instance of DashboardWidget with given ID
            DashboardWidget x = widgetFactory.createWidget(widgetId);
        }
    }

    public List<String> getWidgetList(String user) {
        // load list of IDs of DashboardWidgets to be displayed for the user
    }

    @Autowired
    private WidgetFactory widgetFactory;
}

@Service
public class WidgetFactory {
    public DashboardWidget createWidget(String widgetId) {
        // look up Class<> of DashboardWidget with given id in widgetClasses
        // construct and initialize DashboardWidget
    }

    private HashMap<String, Class<?>> widgetClasses;
}

Bei der Implementierung meiner Widgets möchte ich mich nicht mit der Registrierung des Widgets bei der Factory-Klasse befassen. Im Idealfall würde ich das Widget einfach so kommentieren:

@DashboardWidget(id = "uniqueId")
public class DashboardWidgetA implements DashboardWidget {
    // ...
}

Wenn die Anwendung gestartet wird, sollte sie den Klassenpfad nach @DashboardWidgetAnmerkungen durchsuchen und die Klassen bei der Factory registrieren, damit die Widgets erstellt werden können, indem der createWidget-Methode die ID des Widgets zugewiesen wird.

Im Moment bin ich etwas verwirrt. Ich denke, Spring hat jedes Werkzeug an Bord, um dieses Verhalten zu erreichen. Aber ich kann mir keinen Weg vorstellen, wie es geht.

Hast du einen Rat für mich?

Igor Konoplyanko

Nichts hindert Sie daran, Ihre benutzerdefinierte Anmerkung zu erstellen:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DashboardWidget {}

Dann können Sie die Klassen Ihres Widgets mit Anmerkungen versehen und sie zu Frühlingsbohnen machen. Sie müssen berücksichtigen, ob Sie sie als Singletons (scope = singleton) oder als separate Instanzen pro Benutzer (scope = prototype) haben möchten.

Sie müssen implementieren:

public class WidgetInitializationListener implements ApplicationListener<ContextRefreshedEvent> {

@Override
public void onApplicationEvent(ContextRefreshedEvent event) {

    ApplicationContext context = event.getApplicationContext();
    String[] beanDefinitionNames = context.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        String originalClassName = getOriginalClassName(beanDefinitionName, event);
        if (originalClassName != null) {
            Class<?> clazz = Class.forName(originalClassName);
            if (hasWidgetAnnotation(clazz)) {
                registerSomewhereYourWidget(context, beanDefinitionName, originalClassName);
            }
        }
    }
}

private String getOriginalClassName(String name, ContextRefreshedEvent event) {
    try {
        ConfigurableListableBeanFactory factory =
                (ConfigurableListableBeanFactory)event.getApplicationContext().getAutowireCapableBeanFactory();
        BeanDefinition beanDefinition = factory.getBeanDefinition(name);
        return beanDefinition.getBeanClassName();
    } catch (NoSuchBeanDefinitionException e) {
        LOG.debug("Can't get bean definition for : " + name);
        return null;
    }
}

Meistens hat hier also nichts mit Frühling zu tun, außer dass Sie nur durch Ihre Bohnen laufen, um kommentierte zu finden.

Verwandte Artikel


So initiieren Sie benutzerdefinierte Anmerkungen im Frühjahr

Myborobudur Wenn ich eine Anmerkung zum Festlegen von Klassenfeldern definiere, sieht Folgendes aus: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @interface Set { int value(); } Mit der notwendigen Überlegung: class Injector { public

Verbrauchen Sie benutzerdefinierte Glas im Frühjahr MVC-Projekt

Sturm Ich muss eine Website mit Spring MVC erstellen, damit ich STS für diesen Zweck verwende. Ich benutze Maven auch als Build-Tool. Ich bin neu in Java, daher fällt es mir schwer herauszufinden, wo ich etwas aufbewahren soll oder welcher Verzeichnisstruktur

Wie Implementieren Dekorierermuster im Frühjahr Stiefel

FreeOnGoo: Ich weiß, wie zu implementieren und ein Dekorateur Muster ohne Frühling zu verwenden. Da in diesem Muster, das Sie selbst steuern den Prozess der Erstellung von Komponenten und Sie können dynamisches Verhalten ausführen hinzufügen. Im Folgenden ist