Возможно ли и как сделать вспомогательный впрыск весной? - PullRequest
11 голосов
/ 03 июня 2011

В Guice 2 или 3 существует так называемое Assisted / Partial Inject, описанное здесь . При этом Guice синтезирует фабричную реализацию (реализацию моего интерфейса) для моего объекта, и некоторые аргументы конструктора вводятся Guice , а некоторые предоставляются из контекста.

Возможно ли и как сделать то же самое с Spring?

Ответы [ 2 ]

11 голосов
/ 09 декабря 2012

Следующее делает именно то, что я просил.Хотя он не синтезирует реализацию фабрики, он достаточно хорош, поскольку фабрика имеет доступ к контексту инъекции , чтобы можно было использовать другие bean (инъецируемые артефакты) во время построения.Он использует @Configuration на основе Java вместо XML, но он также будет работать с XML.

Заводской интерфейс:

public interface Robot {

}

// Implementation of this is to be injected by the IoC in the Robot instances
public interface Brain {
    String think();
}

public class RobotImpl implements Robot {

    private final String name_;
    private final Brain brain_;

    @Inject
    public RobotImpl(String name, Brain brain) {
        name_ = name;
        brain_ = brain;
    }

    public String toString() {
        return "RobotImpl [name_=" + name_ + "] thinks about " + brain_.think();
    }
}

public class RobotBrain implements Brain {
    public String think() {
        return "an idea";
    }
}

// The assisted factory type
public interface RobotFactory {
    Robot newRobot(String name);
}

// это конфигурация Spring, показывающая, как сделать вспомогательную инъекцию

@Configuration
class RobotConfig {

    @Bean @Scope(SCOPE_PROTOTYPE)
    public RobotFactory robotFactory() {
        return new RobotFactory() {

            @Override
            public Robot newRobot(String name) {
                return new RobotImpl(name, r2dxBrain());
            }
        };
    }

    @Bean @Scope(SCOPE_PROTOTYPE)
    public Brain r2dxBrain() {
        return new RobotBrain();
    }
}

Тестовый код:

public class RobotTest {

    @Test
    public void t1() throws Exception {
        ApplicationContext ctx = new 
                           AnnotationConfigApplicationContext(RobotConfig.class);
        RobotFactory rf = ctx.getBean(RobotFactory.class);
        assertThat(rf.newRobot("R2D2").toString(), 
           equalTo("RobotImpl [name_=R2D2] thins about an idea"));
    }

}

Это достигается именно таким, как Guiceделает.Сложная разница - Scope.По умолчанию Spring имеет значение Singleton, а Guice - нет (это прототип).

4 голосов
/ 03 июня 2011

AFAIK вы не можете.Весной вы можете иметь Инстанцирование с использованием статического фабричного метода или Инстанцирование с использованием фабричного метода экземпляра .Со вторым параметром вы можете определить компонент myFactoryBean, работающий как фабрика для другого компонента.Вы также можете передать аргументы конструкции в myFactoryBean, используя constructor-arg (см., Например, раздел Использование метода фабрики экземпляров в этом блоге ), который дает вам эквивалент аргументов, введенных Guice.Тем не менее, я не знаю способа предоставить дополнительные аргументы из контекста при вызове фабричного метода.

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