Авто-литые весенние бобы - PullRequest
6 голосов
/ 01 мая 2009

Есть ли способ автоматического приведения bean-компонентов Spring к классу, определенному в контексте XML приложения? Я хотел бы избежать размещения информации о типах bean-компонентов в 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) или получить тип из самого компонента, но нет способа автоматически привести тип без вмешательства программиста.

Ответы [ 6 ]

10 голосов
/ 01 мая 2009

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

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

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

Тогда вы можете позвонить без каста

MyClass mc = MyContextHolder.getBean("myClassBean");
4 голосов
/ 01 мая 2009

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

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

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

1 голос
/ 02 мая 2009

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

Тем не менее, вам следует избегать прямого поиска бобов и максимально сократить их использование.

1 голос
/ 01 мая 2009

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

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.)

0 голосов
/ 12 августа 2010

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

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

0 голосов
/ 21 сентября 2009

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

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

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

...