1

How do I not instantiate Spring Security until I need to?

I'm using Google App Engine so the startup time of my web app is important. Sometimes when a user requests a page, they must wait the whole time for my web app instantiate before getting a response (this is called a loading request).

Certain pages of my app require no authentication. For these pages, if the request is a loading request, I don't want the user to have to wait the extra ~1.5 seconds for Spring Security to instantiate.

I've already figured out how to lazy load all of the other components of my app, Spring Security is the only one I don't know how. Anyone have an idea?

EDIT: If anyone knows how to instantiate Spring Security from code instead of using applicationContext-security.xml, then I think I could figure out how to lazy load it.

Kyle
  • 21,377
  • 37
  • 113
  • 200

3 Answers3

1

Well, I finally figured it out. I had to subclass org.springframework.web.context.ContextLoaderListener and org.springframework.web.filter.DelegatingFilterProxy to not do anything until I call an activate method on them.

Kyle
  • 21,377
  • 37
  • 113
  • 200
  • What did you ended up doing exactly? I'm facing pretty much the same problems. – hleinone Nov 06 '10 at 19:56
  • @hleinone - In the end I ended up getting rid of Spring altogether. I'd recommend not really worrying about lazy loading spring though. I don't think cold starts will really be a problem in the future. See http://blog.listry.com/2010/10/app-engine-warm-up-requests-death-of.html – Kyle Nov 07 '10 at 23:33
  • I really hope your assumption will become reality! – hleinone Nov 07 '10 at 23:39
  • I don't understand your solution. Can you explain a bit about ContextLoaderListener, DelegatingFilterProxy. Here is my scenario on spring security lazy loading at runtime. https://stackoverflow.com/questions/68831257/lazy-initialise-spring-security-at-runtime-reload-spring-security-configuratio Still I didn't get any proper solution for this. – ARods Aug 24 '21 at 14:26
1

The hack described here worked for me:

...you can solve this issue with any LazyInitTargetSource for the UserDetailsService.

<bean id="userDetailsService" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource">
        <bean class="org.springframework.aop.target.LazyInitTargetSource">
            <property name="targetBeanName" value="targetUserDetailsService"/>
        </bean>
    </property>
</bean>

<bean id="targetUserDetailsService" class="MyCustomUserService" lazy-init="true">
    ....
</bean>
Remco Bos
  • 11
  • 1
0

You can configure <url-pattern>s of Spring Security filter mapping in web.xml to match the secured resources only (as well as login-logout pages and other resources which require the Spring Security processing), and wrap the default filter with your own lazy wrapper, as you did with DispatcherServlet.

EDIT: The problem seems to be more complex than I thought. You can also try to define your security xml as <beans default-lazy-init="true" ...>

axtavt
  • 239,438
  • 41
  • 511
  • 482
  • The problem I'm having with Spring Security is that simply having the applicationContext-security.xml defined causes Spring Security to instantiate. I tested this by completely commenting out the Spring Security web.xml filter declaration altogether, yet still having the xml configuration. If I could figure out how to instantiate everything that the xml does, but do it in code, then I think that would work. – Kyle Jan 25 '10 at 18:16