Вопрос

Есть ли способ автоматически приводить бины 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 ) или получить тип из самого bean-компонента, но нет способа автоматически привести тип без вмешательства программиста.

Это было полезно?

Решение

Я согласен с 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");

Другие советы

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top