Почему вообще нет файла конфигурации для внедрения зависимостей в Google Guice? - PullRequest
12 голосов
/ 19 апреля 2009

Я проверяю Google Guice как DI framework , но я немного озадачен: почему вообще нет файла конфигурации?

Я нашел частичное объяснение этого вопроса , но до сих пор не ясно, как я смогу установить роли своих компонентов (или любую другую вещь, в которой мне нужно использовать переключатель) без файла конфигурации.

Любая помощь приветствуется!

Ответы [ 6 ]

28 голосов
/ 19 апреля 2009

Конфигурация находится в коде, а не в файлах конфигурации, что является допустимым решением для многих сценариев.

Да, это означает, что вам нужно пересобрать (возможно, только модули), если вы хотите использовать другой способ подключения вашего приложения - хотя, конечно, вы все равно можете получить некоторые значения конфигурации из аргументов командной строки, файлов свойств и т. Д. если хочешь.

Если вам регулярно нужно менять сантехнику приложения и не хотите повторно развертывать что-либо, кроме одного файла, Guice может не подойти вам. Если, с другой стороны, ваша основная причина использования DI состоит в том, чтобы сделать ваш код более понятным, и в производстве вы всегда будете использовать одну и ту же систему слежения (или достаточно близко), тогда Guice - хороший вариант - часто вам нужны кусочки логики в любом случае использовать при сортировке сантехники и компонентов, которые обычно сложно описать / построить декларативно.

Различные структуры DI имеют разные преимущества и недостатки - используйте ту, которая наиболее подходит для вашего приложения.

7 голосов
/ 18 декабря 2009

Если вы склонны, вводить начальную загрузку с помощью файлов конфигурации просто. Мы используем Guice вместе с простым API, который загружает файлы свойств, куда идут вещи, которые действительно должны быть параметризованы. Это можно использовать вместе с аннотациями @Named и тому подобным, и, конечно, у вас могут быть некоторые условные выражения в модулях (хотя не стоит переусердствовать).

Это пример того, как настроена часть нашей начальной загрузки:

public class MetModules extends AbstractModule {

    private static final Logger log = LoggerFactory.getLogger(MetModules.class);

    private final Settings settings;

    public MetModules(Settings settings) {
        this.settings = settings;
    }

    @Override
    protected void configure() {

        // common (stage independent modules) go here
        install(new CommandsModule());
        install(new ServletsModule());
        install(new DataBaseModule(settings));
        install(new JobsModule(settings));

        // any development/ production specific modules
        Stage stage = currentStage();
        if (Stage.DEVELOPMENT.equals(stage)) {
            configureForDevelopment();
        } else { // PRODUCTION
            configureForProduction();
        }
    }

    /**
     * Install modules that will be used in development.
     */
    private void configureForDevelopment() {

        // Mock implementation of email delivery that just logs it got a
        // message rather than trying to send it.
        install(new AbstractModule() {
            @Override
            protected void configure() {
                bind(Delivery.class).toInstance(new Delivery() {

                    public String deliver(MailMessageExchange exchange)
                            throws DeliveryException {
                        log.info("email message: "
                                + exchange.getMessage().getMailMessage()
                                + " to "
                                + Arrays.asList(exchange.getMessage()
                                        .getMailMessage().getTo())
                                + " (not sent)");
                        return "fooMessageId";
                    }
                });
            }
        });

        // local in-memory registry suffices
        install(new LocalServiceRegistryModule());

        // local in memory db implementations of services
        install(new LocalServicesModule());
    }

    /**
     * Install modules that will be used in production.
     */
    private void configureForProduction() {
        // we really only need this (error interception and audit logging)
        // in production
        install(new AopModule());
        install(new ZooKeeperServiceRegistryModule());      }
}

Где Настройки - это то, что читает наши файлы свойств и тому подобное. В данный момент разработка / производство вместе с определенными переопределениями настроек, специфичными для развертываний, похоже, сделают для нас эту работу, но мы могли бы пойти дальше с этим, если бы захотели.

5 голосов
/ 19 апреля 2009

Большая часть конфигурации DI будет одинаковой от одного развертывания к другому, поэтому их можно очень легко настроить с помощью кода, что делает настройку Guice очень краткой, и вы получаете преимущества от проверки типов во время компиляции, инструментов рефакторинга, навигации по коду и т.д.

Для тех немногих вещей, которые изменяются от развертывания к другому, таких как имя пользователя базы данных и конфигурация пароля, вы можете написать необходимый код самостоятельно. Напишите код, который читает файл конфигурации (возможно, файл свойств), анализирует параметры и связывает их в ваших модулях Guice, чтобы ваше приложение получало к ним доступ. Код, необходимый для этого, не займет много строк кода.

4 голосов
/ 19 апреля 2009

Много настроек в Guice неявно, через аннотацию @Inject. Большая сложность в проектах связана с большим количеством проектных артефактов. Java-файлы, Xml-файлы, файлы свойств, базы данных, параметры. Guice пытается удалить часть этой сложности, не используя конфигурационные файлы.

Перемонтирование вашего приложения легко во время компиляции. Скорее всего, вам нужно всего лишь отредактировать класс вашего модуля. Для большинства классов, управляемых Guice, вам вообще не понадобится конфигурация, а только @Inject в нужных местах - вам нужно будет что-либо конфигурировать только тогда, когда у вас есть две разные реализации одного и того же интерфейса или когда вы хотите внедрить классы внешние библиотеки с использованием классов провайдера.

1 голос
/ 15 августа 2010

Я недавно создал следующий проект.

http://code.google.com/p/guice-property-injector/

Это WIP, но допускает внедрение свойств во время выполнения из файла свойств в зависимости от среды.

1 голос
/ 19 апреля 2009

Не уверен, что вы подразумеваете под файлом, но Guice позволяет вам изменять реализации с помощью Binder и пользовательских Поставщиков .

...