Spring BeanFactory как синглтон в приложении Swing - PullRequest
0 голосов
/ 18 марта 2011

В настоящее время я выполняю рефакторинг большого Swing приложения, чтобы получить некоторые объекты из XmlBeanFactory .

Многие различные классы могут использовать его, и мне интересно, что былучший способ поделиться этим beanFactory.

  • если я создам синглтон для совместного использования этого XmlBeanFactory?

    class Singleton {public static XmlBeanFactory getBeanFactory () {(...)}}

  • или я должен добавить некоторые сеттеры к моему объекту (некрасиво: это добавляет некоторые зависимости ...)

  • другое решение?

Спасибо

1 Ответ

2 голосов
/ 18 марта 2011

Использование статического синглтона - это нормально. Я еще не нашел лучшего решения. Это немного неудовлетворительно, потому что синглтон должен быть инициализирован с помощью файла разводки перед его использованием, и невозможность сделать это приводит к исключениям при создании bean-компонента, это еще одна вещь, которую нужно помнить.

public final class SpringUtil {

private static ApplicationContext context = null;
private static Set<String> alreadyLoaded = new HashSet<String>();

/**
 * Sets the spring context based off multiple wiring files. The files must exist on the classpath to be found.
 * Consider using "import resource="wiring.xml" in a single wiring file to reference other wiring files instead.
 * Note that this will destroy all previous existing wiring contexts.
 * 
 * @param wiringFiles an array of spring wiring files
 */
public static void setContext(String... wiringFiles) {
    alreadyLoaded.clear();
    alreadyLoaded.addAll(Arrays.asList(wiringFiles));
    context = new ClassPathXmlApplicationContext(wiringFiles);
}

/**
 * Adds more beans to the spring context givin an array of wiring files. The files must exist on the classpath to be
 * found.
 * 
 * @param addFiles an array of spring wiring files
 */
public static void addContext(String... addFiles) {
    if (context == null) {
        setContext(addFiles);
        return;
    }

    Set<String> notAlreadyLoaded = new HashSet<String>();
    for (String target : addFiles) {
        if (!alreadyLoaded.contains(target)) {
            notAlreadyLoaded.add(target);
        }
    }

    if (notAlreadyLoaded.size() > 0) {
        alreadyLoaded.addAll(notAlreadyLoaded);
        context = new ClassPathXmlApplicationContext(notAlreadyLoaded.toArray(new String[] {}), context);
    }
}

/**
 * Gets the current spring context for direct access.
 * 
 * @return the current spring context
 */
public static ApplicationContext getContext() {
    return context;
}

/**
 * Gets a bean from the current spring context.
 * 
 * @param beanName the name of the bean to be returned
 * @return the bean, or throws a RuntimeException if not found.
 */
public static Object getBean(final String beanName) {
    if (context == null) {
        throw new RuntimeException("Context has not been loaded.");
    }
    return getContext().getBean(beanName);
}

/**
 * Sets this singleton back to an uninitialized state, meaning it does not have any spring context and
 * {@link #getContext()} will return null. Note: this is for unit testing only and may be removed at any time.
 */
public static void reset() {
    alreadyLoaded.clear();
    context = null;
}

}

В более новых версиях Springframework вы можете использовать обобщенные значения, чтобы getBean () возвращал более конкретный класс, чем Object, поэтому вам не нужно приводить свой бин после его получения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...