Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Spring dependency injection в сервлетоы и фильтры


Автор: illarion 17.9.2009, 11:29
В нашем проекте было очень много примеров неправильного использования Spring IoC, вида:

Код

MyClass instance = applicationContext.getBean("someBean");


Эти неявные зависимости я почти везде уже устранил, но столкнулся с тем, что в фильтры и сервлеты, жизненным циклом которых управляет контейнер (в нашем случае Tomcat), инжектить ничего нельзя. Официальная документация по этому поводу молчит. Как быть? Может кто-то уже сталкивался с такой ситуацией?

Автор: garbuz 17.9.2009, 12:55
Я недавно в сервлете бин доставал. Делал вот так
Код

 WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
 ApplicationService applicationService =(ApplicationService)springContext.getBean("applicationService");

Автор: illarion 17.9.2009, 13:03
Цитата(garbuz @ 17.9.2009,  12:55)
Я недавно в сервлете бин доставал. Делал вот так
Код

 WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
 ApplicationService applicationService =(ApplicationService)springContext.getBean("applicationService");

Это как раз пример того, как сделано сейчас. Это не совсем корректно и не совсем красиво. Если бы спринг умел инстанцировать сервлеты и фильтры сам, то можно было бы их объявить как обычные бины, настроив для них properties. В самом же коде сервлета были бы лишь простые сеттеры.

Автор: garbuz 17.9.2009, 15:51
Цитата(illarion @  17.9.2009,  13:03 Найти цитируемый пост)
то как раз пример того, как сделано сейчас. Это не совсем корректно и не совсем красиво. Если бы спринг умел инстанцировать сервлеты и фильтры сам, то можно было бы их объявить как обычные бины, настроив для них properties. В самом же коде сервлета были бы лишь простые сеттеры. 

Видел где-то, сейчас к сожалению не найти, пример, где расширялся класс HttpServlet, экземпляры которого могли потом использоваться как простые бины, котрым было достаточно сеттеров. Т.е. то что вам надо. Советую поискать. Можно конечно самому попробывать реализовать smile

Автор: _sten_ 23.9.2009, 23:56
думаю стоит почитать о Spring MVC

Автор: garbuz 24.9.2009, 00:19
Цитата(_sten_ @  23.9.2009,  23:56 Найти цитируемый пост)
думаю стоит почитать о Spring MVC 

Иногда полный Spring MVC бывает лишним, например нужен всего один сервлет для обработки ajax запросов, а в этот сервлет надо проинжектить объект какого-либо сервиса.
illarion, я кстати нашел ссылку. Метод номер 3 
http://andykayley.blogspot.com/2007/11/how-to-inject-spring-beans-into.html

Автор: MisterCleric 24.9.2009, 10:06
Цитата

я кстати нашел ссылку. Метод номер 3 

А чем этот способ отличается от:
Код

 WebApplicationContextUtils.getWebApplicationContext(getServletContext());


То же самое только инкапсулировано в определенном классе.
Я, к стати, тоже интересовался такими методами "автоваринга" для связки EJB3+Spring и там есть что-то подобное показанное garbuz.
Вешается на EJB интерцептор, который и будет производить инъект Spring-бинов в проперти, помеченные как @Autowired
Я думаю, все-таки, в данном случае надо смотреть в сторону Spring MVC.

Да, что бы далеко не ходить даже спринговцы используют "бракуемый" в данной теме способ. Вот пример исходников одного из их классов:
Код


package org.springframework.web.context.support;
public class HttpRequestHandlerServlet extends HttpServlet {

    private HttpRequestHandler target;


    public void init() throws ServletException {
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
        this.target = (HttpRequestHandler) wac.getBean(getServletName(), HttpRequestHandler.class);
    }
.....
}

Автор: magicfly 28.9.2009, 17:23
http://www.acegisecurity.org/acegi-security/apidocs/org/acegisecurity/util/FilterToBeanProxy.html

есть такая вещь, используется как видно в spring-security. Возможно стоит покопать туда

Автор: MisterCleric 29.9.2009, 09:54
Привет.
Нашел: тебе действительно ничего писать не надо. Есть такой класс у Spring:
Код

<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>


где имя фильтра имя бина в Spring-контексте.

Добавлено через 4 минуты и 17 секунд
Твой бин всего лишь должен быть как " implements Filter", а дальше делаешь свои инджекшены как обычно

Автор: illarion 5.10.2009, 13:30
Что же касается сервлета, то все еще проще - он должен реализовывать интерфейс HttpRequestHandler

Код

public class MyServlet extends HttpServlet implements HttpRequestHandler {

  private String myProperty;

  public void setMyProperty(String value){
    this.myProperty = value;
  }

...

}


в application context пишем:
Код

    <bean id="MyServlet" class="com.test.MyServlet">
        <property name="myProperty" value="test" />
    </bean>


а в web.xml пишем такое:

Код

    <servlet>
        <servlet-name>MyServlet</servlet-name>
        <display-name>MyServlet</display-name>
        <description></description>
        <servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
    </servlet>

Автор: illarion 9.10.2009, 08:53
В общем, в итоге в проекте осталсь лишь SessionListener и еще парочку, в которые непонятно как инжектить. Фильтры и сервлеты работают через HttpRequestHandlerServlet и DelegatingFilterProxy. 

Автор: Старовъръ 10.10.2009, 11:54
Если приложение большое, то, как советовали выше, нужно глядеть в сторону SpringMVC или другого MVC framework.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)