Есть элегантный способ вставить spring управляемый bean в пользовательский/простой тег java
У меня есть куча java-пользовательских тегов, которые используют spring управляемый beans.., так как я не могу найти способ вставить в пользовательский тег, я создал вспомогательный класс, который предоставляет статические методы для getProObjectINeedBean() для всех объектов spring bean, которые мне нужны. Мне совсем не нравится этот подход.
Я действительно хочу иметь возможность вставлять spring управляемый bean в пользовательский тег
Есть ли способ? Что касается моих исследований, я понимаю, что нет никакого способа сделать это, потому что пользовательский тег управляется контейнером
Спасибо,
Билли
Ответы
Ответ 1
Вы правы, что нет простого способа использования инъекции зависимостей в тегах jstl, потому что они не управляются spring и не могут быть. Однако есть (по крайней мере) два обходных пути:
-
@Configurable
- aspectJ позволяет подключать ткача во время загрузки/компиляции, так что даже объекты, которые не создаются с помощью spring, могут быть spring осведомлены. См. здесь
-
Вы можете создать базовый класс тега для своего проекта и вызвать метод init(..)
из каждого метода doStartTag(..)
. Там вы можете получить ServletContext
из pageContext
и получить spring ApplicationContext
(через ApplicationContextUtils
). Тогда:
AutowireCapableBeanFactory factory = appCtx.getAutowireCapableBeanFactory();
factory.autowireBean(this);
Ни один из вариантов не идеален, поскольку для этого требуется либо некоторый дополнительный код, либо некоторая "черная магия"
Ответ 2
Чтобы перейти на пост @Bozho, я получил это, чтобы он работал следующим образом: (в spring 3.0 нет ApplicationContextUtils, который я мог найти)
public class LocationTag extends RequestContextAwareTag {
@Autowired
PathComponent path;
...
@Override
protected int doStartTagInternal() throws Exception {
if (path == null) {
log.debug("Autowiring the bean");
WebApplicationContext wac = getRequestContext().getWebApplicationContext();
AutowireCapableBeanFactory acbf = wac.getAutowireCapableBeanFactory();
acbf.autowireBean(this);
}
return SKIP_BODY;
}
}
Ответ 3
Решение, описанное выше, работает, но некоторые фоновые и дополнительные фрагменты кода, вполне вероятно, полезны.
1) Метод doStartTagInternal вызывается методом doStartTag.
2) Я был вынужден установить pageContext сначала, прежде чем использовать doStartTag
3) Я просмотрел bean, в отличие от автоустройства. Для меня это кажется более простым: (YourBeanProxy) autowireCapableBeanFactory.getBean( "yourBeanName" )
Надеюсь, эта дополнительная информация полезна.