Авто-литье Spring Beans

Есть ли способ автоматического создания Spring beans для класса, определенного в XML-контексте приложения? Я бы хотел не помещать информацию о типе beans в 2-х местах.... в файле конфигурации xml, а также в коде как литье.

Например, данный конфигурационный файл

<bean id="bean-name" class="SimpleSpringBean"  scope="prototype">
    <property name="myValue" value="simple value"></property>
</bean>

Можно ли вызвать ApplicationContext.getBean("bean-name") таким образом, чтобы избежать прямого перевода возвращаемого типа на SimpleStringBean. Я знаю, что я также могу вызвать ApplicationContext.getBean("bean-name", SimpleSpringBean.class), чтобы избежать самого трансляции, но у меня все еще есть информация о типе в 2-х местах.

Кажется, что Spring может получить информацию о классе (ApplicationContext.getType) или получить тип из самого bean, но не может автоматически применять тип без вмешательства программиста.

Ответ 1

Я согласен с Sii, вам следует избегать вызова getBean столько, сколько сможете. Просто подключите beans к классам, которые зависят от них.

Тем не менее, если у вас есть один класс, который содержит контекст приложения, вы можете предоставить общий метод обертки, например:

class MyContextHolder{
    ApplicationContext appContext;
    ......
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName)
    {
        return (T)appContext.getBean(beanName);
    }
}

Затем вы можете вызвать его без кастования

MyClass mc = MyContextHolder.getBean("myClassBean");

Ответ 2

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

Кроме того, то, что вы спрашиваете, возможно, вообще невозможно на языке Java. Кастинг - это функция времени компиляции в сочетании с проверкой времени выполнения. Тип возврата getBean() просто должен быть известен во время компиляции. Даже если Spring может определять тип объекта, он не может изменить свои собственные сигнатуры метода во время выполнения.

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

Ответ 3

Другим подходом, который я также использую, является autowiring класс начальной загрузки, используя:

public class Main {
    @Autowired FooFacade foo;
    @Autowired BarFacade bar;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
        Object main = bf.createBean(Main.class, 
                                    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
                                    false);
        ((Main) main).run();
    }

    private void run() {
        foo.doBootstrapStuff();
        bar.doMoreBootstrapStuff();
    }
}

(Код выполнен из памяти. Может работать только в том случае, если у вас есть контекст Spring, сконфигурированный для обработки аннотаций проводки, в этом случае работающие сеттеры для foo и bar должны работать.)

Ответ 4

Основной причиной отсутствия getBean является совместимость Spring (до версии 2.5.x) с Java 1.4. Spring 3.0 упадет и, таким образом, предложит тип getBean.

Тем не менее вы должны избегать прямого поиска beans и максимально минимизировать его использование.

Ответ 5

Что делать, если я использую Spring как объект factory, который мое приложение использует широко. То есть вместо того, чтобы писать кучу классов, которые уже наследуют или обертывают известных Java-классов, я просто решил переместить все это в XML файл, чтобы сократить строки кода Java. Это будет означать много строк xml, но мне не нужно будет делать скелетные классы Java, которые я вставляю с помощью Spring или autowire. Таким образом, создание линий кода Java меньше.

По этой причине и все еще, поскольку я новичок в Spring, я точно так же заявил в предыдущем в сообщениях использовались статические методы Java, которые обтекают getBeans().

Я работал с Spring, но он по-прежнему новичок для меня, поэтому простите мой вопрос.

Ответ 6

"Поскольку Spring AOP реализуется с использованием динамических прокси, вы почти всегда хотите, чтобы Spring передал вам экземпляр интерфейса, который реализует bean (который может быть прокси-сервером AOP), а не класса реализации"

Итак, нет способа получить динамический прокси-сервер с помощью getBean(), а что лучше всего, если нет интерфейсов и его отдельный класс драйвера для выполнения?