0

I had previously used Spring MVC and hibernate annotations in my Google web application project. It is taking some time to start the application after deployment.

For that reason, I am switching to a Spring MVC XML-based approach for the controller only. However, for service and DAO classes, @Service and @Repository annotations remain as is.

In my Spring XML I am doing as like below (there is no bean tag defined for service and DAO classes):

<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
<bean class="com.my.controller.UserController">
    <property name="domainManager" ref="domainManager"/>
    <property name="userProfileDao" ref="userProfileDao"/>
</bean>

Inside UserController, I am not using any @autowired annotation. I am using combination of annotations with XML. Are there any drawbacks of this approach? Am I going about this the wrong way?

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
RBP
  • 481
  • 1
  • 9
  • 29
  • You can mix flavors of Spring DI just fine, and people do it all the time. I don't know how that will help speed up the application startup time, nor why one would care as to how long the app takes to start, but then again I don't know your requirements. Just an FYI, Spring Apps typically suffer from slower startup because all the "heavy lifting" of DI that occurs at startup, which typically means lots of Singleton classes getting built up-front. But the up-front cost usually means less time doing GC and building objects later. – CodeChimp Apr 10 '14 at 11:17
  • For Google app project , every request should need to finish within 30 sec or 1 m. I am not expert in Spring mvc, As per my observations using annotations after deployment, it takes long time to start app, as all dependencies has to set and configuration is done in first request. but for xml based approach dependencies set at compile time. please correct me if my understanding is wrong.? – RBP Apr 10 '14 at 12:25
  • That is totally not true. Regardless if you use annotation-based or XML based, DI happens at startup, unless you mark your beans as prototypes, in which case they are created upon each request. XML does not do anything at all in compile time, so again I am curious as to why you are perceiving a speed increase at startup when using XML over annotation-driven. Unless you are telling Spring to scan ALL packages for annotated classes, but then you are misusing Spring at that point. Also, this 30sec time limit, is this on requests or for an app to be in "ready" state (startup)? – CodeChimp Apr 10 '14 at 12:33
  • yes. when i deploy and hit the url, it didn't load as request need to finish within 30 sec. Hitting url many times then webpage is coming and this is problem. In my spring xml file, I have given base package name of all annotated packages and classes. so is it wrong.? what i need to do there to avoid misuse.? – RBP Apr 10 '14 at 12:44
  • If you are using Annotation Config with a specific non-common package root then you are fine. That aside, the first time you hit a JSP it has to compile, unless you are pre-compiling them into your WAR prior to deployment. Could this possibly be the issue you are seeing? This has nothing to do with Spring or how it's configured, it's just how JSPs work. For what it's worth, if you want help, we need a LOT more details. I am not talking about pasting all your code or anything, but in general relevant code plus expected and perceived output would be a good start. – CodeChimp Apr 10 '14 at 13:51
  • @CodeChimp : there is a performance difference between XML and autowiring that is specific to the App Engine runtime, see my answer – Michael Técourt Apr 10 '14 at 16:53
  • Sure, I can see there is a *slight* difference between autowiring/component scanning and direct DI, but I wouldn't expect it to be a massive difference, unless you were scanning ALL the packages. Even most large-scale web apps consist of maybe 1000 or so classes. I would think on a relatively decent platform the difference would be negligible. Again, I would think most of the time is spent in instantiating the Singletons, not in scanning and wiring them together. I would love to see some concrete numbers to prove me wrong. – CodeChimp Apr 11 '14 at 11:30
  • @CodeChimp I would like to see the numbers too. I understand the principles and I have perceived the performance issue, I don't know the exact time factor though. The only person who has gone deep enough through this issue works for pivotal, and Google does not seem all that interrested in Spring's performance on their platform. – Michael Técourt Apr 11 '14 at 13:53

1 Answers1

0

The difference is not between using Annotation or XML, it's between Autowiring and "manually injecting beans".

EDIT: @Autowired and XML component scan are doing the same thing.

You can "manually inject" beans with both XML and full Java @Configuration, the equivalent of your example would be :

@Configuration
public class WebAppConfig {

   @Bean
   public UserDao userDao() {
     return new UserDao();
   }

   @Bean
   public UserController userController() {
     UserController ctrl = new  UserController();
     ctrl.setUserDao(userDao());
     return ctrl;
   }

}

The question is quite accurate because the App Engine team itself has revealed that the App Engine runtime was bad at classpath scanning (which Autowiring does to find matches by Class).

The performance loss at instance startup time would occur if you were doing :

public class UserController {

   @Autowired
   private UserDao userDao;

   // ...
}

See this video, especially the question from the Pivotal (Spring framework) contributor : http://www.youtube.com/watch?v=lFarE1hH0ss

Few people know about this issue. Using Spring AOP can even totally crash on the production runtime. See : Using Spring AOP on App Engine causes StackOverflowError

So about your use of XML, there is no "right or wrong". Personally I don't like writing XML since I feel like it's more error prone, but some people like to clearly separate their configuration from their code. I still use autowiring in production, since the startup time is not an issue for me. Do what you and your team feel comfortable with, just keep in in mind the GAE limitations.

Community
  • 1
  • 1
Michael Técourt
  • 3,457
  • 1
  • 28
  • 45
  • Yes,I am facing this start time issue.So i went to xml based approach But doing this also, getting same problem then It is better to keep previous annotation based approach as it is.How are you dealing with startup time ? can give me some suggestion to overcome with it? If you need some of my code , i can paste it.I have given base pkg name in component scanning. please guide me to overcome this issues. – RBP Apr 11 '14 at 06:23
  • Well in the end I didn't handle start up time, I paid for a couple idle instances that just stayed up : https://developers.google.com/appengine/docs/adminconsole/performancesettings#Setting_the_Number_of_Idle_Instances ... You could also possibly ping your app or define a cron job to keep it up : http://stackoverflow.com/questions/1113066/how-to-keep-an-app-engine-java-app-running-with-deaf-requests-from-a-java-python .. When my app NEEDED this to keep my customers on board, I just paid for peace. – Michael Técourt Apr 11 '14 at 07:41
  • hmmm.I am using cron jobs to keep application alive.one small question, can i set dependencies into xml like i have mentioned before instead to use @autowired annotation ? will it decrease scaning time ? and will it increase performance little bit..? – RBP Apr 11 '14 at 09:24
  • Using XML will certainly improve startup time if you don't use ` ` -- I don't have measurables though – Michael Técourt Apr 11 '14 at 13:46
  • okie.I have one question in my mind. when i used cron jobs , application's start time decrease to certain amount.Without cron job it take long time to start application and i was hitting url again and again to start it. I want to know why using cron jobs application's start up time decrease to some amount. – RBP Apr 12 '14 at 18:15
  • 1
    the cron jobs do not decrease start up time, it prevents your app from starting up by "not allowing it to sleep". In the end you have two approaches : try to lower startup time by understanding the plumbing of GAE (classpath scanning, etc), or find a way for your app to stay up (cron jobs that run periodically, external process that pings your app, paying...) – Michael Técourt Apr 14 '14 at 08:01
  • I did some google on component:scan , as per information only Autowired, Service,Controller,dao,component annotations comes under component scan annotation.If i remove '' then will it affects on RequestMapping, ResponseBody, Table, Id(Hibernate) annotations etc.? – RBP Apr 23 '14 at 10:03