Spring MVC, Spring Security и Hibernate не могут автоматически связывать свойства между контекстами

Я использую Spring MVC 3.0.6 и Spring security 3.0.7. Я не могу @Autowire класса RoleDao для моего пользовательского класса, когда в контексте безопасности.

мой файл web.xml:

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>



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

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Security-app-context.xml:

<beans:bean id="chineseCheckersEntryPoint" class="com.nike.golf.security.ChineseCheckersAuthenticationEntryPoint" />

<beans:bean id="chineseCheckersFilter" class="com.nike.golf.security.ChineseCheckersAuthenticationFilter">
    <beans:property name="authenticationManager" ref="authenticationManager"/>
</beans:bean>

<http use-expressions="true" auto-config="false" entry-point-ref="chineseCheckersEntryPoint">
    <intercept-url pattern="/secure/extreme/**" access="hasRole('supervisor')" />
    <intercept-url pattern="/user/**" access="permitAll" />
    <intercept-url pattern="/profile/**" access="isAuthenticated()" />
    <intercept-url pattern="/secure/**" access="isAuthenticated()" />
    <custom-filter position="PRE_AUTH_FILTER" ref="chineseCheckersFilter" />
</http>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="chineseCheckersAuthenticationProvider" />
</authentication-manager>

<beans:bean id="chineseCheckersAuthenticationProvider" class="com.nike.golf.security.ChineseCheckersAuthenticationProvider" />

В моем пользовательском объекте, где он использует roleDao, он нулевой. Он не был подключен автоматически. Из всех исследований, которые я провел в Интернете, похоже, что они связаны с различными контекстами и невозможностью автоматической связи между ними.

Может ли кто-нибудь помочь мне понять эти контексты и как я могу привести их в один и тот же контекст?

2 ответа

Решение

Спасибо всем за вашу помощь. Мне удалось это выяснить.

Этот вопрос был похож на мой и заставил меня двигаться в правильном направлении: объявление Spring Bean в родительском контексте против дочернего контекста

Этот пост на форуме действительно упростил эту идею для меня.

В вашем файле web.xml вы определяете контекст сервлета и контекст приложения. Контекст приложения настраивается с помощью этих частей XML:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring/root-context.xml
        /WEB-INF/security-app-context.xml
    </param-value>
</context-param>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

любое количество файлов *context.xml, которые вы передаете в context-param> contextConfigLocation, находится в контексте приложения. Это родительский контекст.

Контекст сервлета создается в файле web.xml следующим битом xml:

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Контекст сервлета как дочерний контекст имеет доступ к контексту приложения (родительский).

Это было ключевым для меня, чтобы понять. Поэтому я перенес всю конфигурацию, которая была у меня в контексте сервлета, в контекст приложения.

Как и ответ на другой вопрос, на который я ссылался выше, @Autowired все еще не работает. Кто-нибудь знает причину этого? Таким образом, чтобы обойти это, я определил bean-компоненты и свойства в xml от самого свойства, которым я занимался, до sessionFactory.

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

В моем вопросе я даже не опубликовал файл servlet-context.xml, потому что не думал, что к нему нужно прикасаться, но на самом деле мне нужно было перенести конфигурацию в контекст приложения, если я хочу подключить что-то к мои бобы безопасности.

Я надеюсь, что в этом есть смысл.

Вы можете представить контекст как набор бобов Spring.

Контексты могут быть вложенными, так что внешний контекст может получить доступ к bean-компонентам из внутреннего, но не наоборот. Примером этого являются типичные веб-приложения, которые имеют два контекста: внутренний, указанный с помощью contextConfigLocation и загружен ContextLoaderListener и внешний настроен с DispatcherServlet,

Один из способов объединения двух XML-файлов в один контекст - введение третьего XML-файла конфигурации приложения, который включает только другие XML-файлы, используя bean:include, И тогда вам остается только указать этот третий xml-файл для загрузчика. Но я не уверен, что вы действительно настроили 2 контекста приложения для ContextLoaderListener , - В любом случае вы можете попробовать трюк с 3. XML-файлом.

Другие вопросы по тегам