title: Declaring Spring Bean in Parent Context vs Child Context
body: <p>I have a spring bean (dao) object which I instantiate in my ServletContext via the following xml:</p>
  
  <pre><code>&lt;bean id="userDao" class="com.company.dao.impl.UserDaoImpl"&gt;
      &lt;property name="sessionFactory" ref="sessionFactory" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>This bean is declared inside my webapp-servlet.xml file and is used by my app within the ServletContext.</p>
  
  <p>I am also using SpringSecurity.  It is my understanding that this runs in a different context (the SecurityContext).</p>
  
  <p>My application has a webapp-security.xml where I instantiate a custom authentication provider.  I would like to use my dao that is used in my app to also do the user lookup in my security context, but when I run:</p>
  
  <pre><code>&lt;bean id="userAuthenticationProvider" class="com.company.security.UserAuthenticationProvider"&gt;
      &lt;property name="userDao" ref="userDao" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>I get errors saying that there is no such bean "userDao".  The bean is autowired fine in beans declared in my other context, but not inside my security context.  According to the Spring Docs, I believe both separate contexts are needed in web.xml</p>
  
  <pre><code>&lt;listener&gt;
      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;
          org.springframework.security.web.session.HttpSessionEventPublisher
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  </code></pre>
  
  <p>So my question is, how can I get access to my DAO that lives in my ServletContext inside my SecurityContext?  Is there a scope modifier for my dao, or could I somehow get the ServletContext at runtime within my authentication provider?  For reference, this is how I want to use it inside my authentication provider:</p>
  
  <pre><code>public class UserAuthenticationProvider extends
      AbstractUserDetailsAuthenticationProvider {
  
      @Override
  protected UserDetails retrieveUser(String userName,
          UsernamePasswordAuthenticationToken authenticationToken)
          throws AuthenticationException {
  
      // use dao here
  </code></pre>
  
  <p>thanks for explaining this to me</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Continuing my investigation, it seems that the DispatcherServlet where I'm using my daos is a child context, and the security context is somewhere higher up.  Consequently, beans in my DispatcherServlet can not be seen by parent contexts.  I think the answer is to move my bean declarations into the parent application context somehow, but i'm not sure how to do this.  Here is my web.xml</p>
  
  <pre><code>&lt;context-param&gt;
      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
      &lt;param-value&gt;WEB-INF/spring-*.xml
      &lt;/param-value&gt;
  &lt;/context-param&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;
          org.springframework.security.web.session.HttpSessionEventPublisher
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;filter&gt;
      &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
      &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy
      &lt;/filter-class&gt;
  &lt;/filter&gt;
  
  &lt;filter-mapping&gt;
      &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;
  
  &lt;servlet&gt;
      &lt;servlet-name&gt;myapp&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet
      &lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;listings&lt;/param-name&gt;
          &lt;param-value&gt;true&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/servlet&gt;
  
      ...
  </code></pre>
  
  <p>I moved all of my dao creation out to a spring-dao.xml, and in my spring-security.xml I am now doing a:</p>
  
  <pre><code>&lt;import resource="spring-dao.xml" /&gt;
  </code></pre>
  
  <p>The daos stil remain visible to the DispatcherServlet context and invisible to my SecurityContext though.</p>
  
  <p><strong>ANSWERED:</strong></p>
  
  <p>Alright, I figured it out.  Here were some helpful links:</p>
  
  <p><a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#context-create" rel="nofollow noreferrer">http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#context-create</a></p>
  
  <p><a href="http://forum.springsource.org/showthread.php?115774-Spring-Security-Custom-UserDetailsService-to-use-User-Service-Dao" rel="nofollow noreferrer">http://forum.springsource.org/showthread.php?115774-Spring-Security-Custom-UserDetailsService-to-use-User-Service-Dao</a></p>
  
  <p><a href="http://static.springsource.org/spring-security/site/faq.html#faq-method-security-in-web-context" rel="nofollow noreferrer">http://static.springsource.org/spring-security/site/faq.html#faq-method-security-in-web-context</a></p>
  
  <p>So the problem was we need to make sure that the dao exists in the ApplicationContext (higher up spring container).  To make sure this happened I changed my web.xml to be:</p>
  
  <pre><code>&lt;context-param&gt;
      &lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
      &lt;param-value&gt;WEB-INF/spring-dao.xml WEB-INF/spring-security.xml
      &lt;/param-value&gt;
  &lt;/context-param&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;listener&gt;
      &lt;listener-class&gt;
          org.springframework.security.web.session.HttpSessionEventPublisher
      &lt;/listener-class&gt;
  &lt;/listener&gt;
  
  &lt;filter&gt;
      &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
      &lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy
      &lt;/filter-class&gt;
  &lt;/filter&gt;
  
  &lt;filter-mapping&gt;
      &lt;filter-name&gt;springSecurityFilterChain&lt;/filter-name&gt;
      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  &lt;/filter-mapping&gt;
  
  &lt;servlet&gt;
      &lt;servlet-name&gt;webapp&lt;/servlet-name&gt;
      &lt;servlet-class&gt;org.springframework.web.servlet.DispatcherServlet
      &lt;/servlet-class&gt;
      &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
      &lt;init-param&gt;
          &lt;param-name&gt;listings&lt;/param-name&gt;
          &lt;param-value&gt;true&lt;/param-value&gt;
      &lt;/init-param&gt;
  &lt;/servlet&gt;
  </code></pre>
  
  <p>I thought this would make sure that the first context loader that starts up will read my dao config (and create my dao beans), then my security config.  Since the dao beans are being created this way, I removed the previous "import resource="spring-dao.xml"" statement in the security.xml because it will no longer be needed.</p>
  
  <p>Right after that context-param configuration I created the ContextLoaderListener.  This is a higher-level spring container than the DispatcherServlet, so I figured putting this first would be the first guy to read those config files, and <em>he</em> would then create the beans.  Then, any child-context would have access to them.  This may not be how it works as DispatcherServlet may not even read the contextConfigLocation, but even if it does, I figured that at this point the beans would already be declared, so too bad, the parent context owns them.</p>
  
  <p>Now, for another trick... in order to get my DAO, I could <em>not</em> @Autowired it.  I had to manually inject it via XML:</p>
  
  <pre><code>    &lt;bean id="userAuthenticationProvider" class="com.company.app.security.UserAuthenticationProvider"&gt;
      &lt;property name="userDao" ref="userDao" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>Of course, I made the getter and setter methods on my dao, and voila!  I do not know why the @Autowired does not work here.  I assume it's by design.  Perhaps this is particular to the SecurityContext (it will not pull from other contexts), or perhaps @Autowired in general <em>only</em> pulls from the current context, or maybe because I created the bean via XML, I have to also set any properties via xml and not via annotations?  (annotations are enabled and working in my top-level application namespace).</p>
  
  <p>Anyways.. still a lot I don't understand, but the important point is it's finally working.</p>