On 2/11/13 11:39 AM, "Frank Zhang" <frank.zh...@citrix.com> wrote:
>Ok. now I understood the story. I will go XML for my components. >I can understand the pain Kelven suffered, CloudStack has some many >components that are hard to convert to XML files at one time, given the >tight schedule we faced on javelin. >So using @Component to make Spring onboard is understandable. > >However, I agree with Darren that we should not use @Component and should >use JSR annotations instead of Spring specific like @Autowired. >@Component is easy, but not feasible and unreadable. By not feasible I >mean you could not use amazing spring constructor/setter injection, you >may argue that you don't need it but if someday you are, then you have to >go XML way which breaks your code convention as you have had @Component >mess everywhere. By unreadable I mean you are not able to tell what's >skeleton of project if you are new to CloudStack. The skeleton are >usually made up of Spring beans, listing these beans in XML file gives >people a chance to grab a global picture quickly, for they don't have to >loss in huge java files for @Component. > >And Spring has some other plus on XML file, it has an extensible >framework that you can add your namespace in bean definition, a beast >tool! > >>> Option 3, Using @Configuration) >Please don't approach to this. @Configuration is not for this. Its main >purpose is using byte-weaver(Aspectj) to do dependency injection on >domain object. A domain object is produced by your code but not Spring >IOC, which means the object generated by java *new* keyword. So >@Configuration is largely for prototype bean, not singleton, this is >usually not you want. > >However, I don't think using Spring specific utilities is a big deal. I >agree that POJO is good, and Spring also encourages people not to lock in >Spring as much as possible. But to a large enterprise project, it would >unlikely switch to another container if current container is stable and >flexible(I mean Spring here you know). Pursuing pure POJO will introduce >boilerplate glue code and make things over-abstract/over-wrapping >sometime. Five years ago I was writing a C framework in Linux, to be >pure, I added a layer of wrapper for some glib component. I told my >architect that I don't want to lock in to glib, he asked back that why >you want to switch to another library as glib has been proved itself for >a long time? > >so, I agree we should be POJO, but just avoid being purist if the gain is >small. Yes, we've paid extra caution not to have tight-binding with Spring except about the usage of @Component annotation at meta level. Since we use it only at meta level, it is now actually easy to generate a bean definition XML file to switch to full XML way, however, I prefer to do it a in later time and would like to hear more developers to comment about it. -Kelven > >> -----Original Message----- >> From: Kelven Yang >> Sent: Monday, February 11, 2013 10:48 AM >> To: Darren Shepherd >> Cc: Frank Zhang; cloudstack-dev@incubator.apache.org >> Subject: Re: what's rule for using @Component and xml bean file >> >> >> >> On 2/9/13 6:54 AM, "Darren Shepherd" <dar...@godaddy.com> wrote: >> >> >Sorry, technical error in sending the last email... >> > >> > >> >Please, please, please do note use spring packages. Spring should be a >> >runtime and not compile time dependency. If you leave spring as a >> >compile time dependency you'll see overtime that developers start >> >leveraging handy spring utilities and components. Architecturally it >> >does make sense to have dependencies on such a large component as >> >spring for utility style functionality, that is what apache commons is >>for. >> > >> >So my two cents. >> > >> >Option 1, Using coding convention to reduce the auto-scan scope,) >> > >> > >> >Not feasible in a realistic time frame >> > >> >Option 2, Using build-time XML auto-generation) >> > >> >Too much of a one off solution. This is just another thing people have >> >to understand that is different from how the majority of people use >> >spring. And its uses a spring specific annotation. >> > >> >Option 3, Using @Configuration) >> > >> >Yeah people don't like XML. But the eclipse support and specifically >> >the Spring IDE support for the XML configuration is awesome. The new p >> >namespace also makes the XML less verbose. So, oh well, write some XML >> >it won't kill you. If you use autowiring you'll find that mostly you >> >are just registering the bean and the XML is quite small. Again, for >> >simplest learning curve to developing and understanding CloudStack just >> >stick with the XML. >> > >> > >> >So again, I'm going to strongly assert that CloudStack should >> > >> >1) Use JSR250, JSR330 annotations (@Inject, @PostConstruct, >> >@PreDestroy) >> >2) Register all beans in XML >> >3) Use autowiring >> >> >> We have hundreds of Bean components in CloudStack, it is quite annoying >>to >> register all of them in XML and to maintain it when code-refactoring is >>still >> going on. So we are taking some compromises here, for your points, we >>are >> definitely using auto wiring, but for 1) and 2), we used one more Spring >> defined annotation (@Component), which may not sound elegant that it has >> Spring dependency, but the dependency is only at meta(annotation) level, >> we have very limited places that require a direct reference to Spring >>at code >> level. >> >> Having some meta level annotations and combining with the flexibility of >> XML is pretty much the census I've got from local CloudStack developers >> around me, this may not the final approach either, let's give it some >>time to >> evolve based on broader feedbacks from the community >> >> -kelven >> >> >> >> > >> >Darren >> > >> >On Feb 9, 2013, at 12:05 AM, Kelven Yang <kelven.y...@citrix.com> >>wrote: >> > >> >> >> >> Apologize for such a long email first, if you are interested, please >> >>read on... >> >> >> >> >> >> Auto-scan globally is never a good idea and we are currently doing it >> >>just for the reason of getting existing code quickly converted. I'm >> >>currently profiling some details on how much time Spring has spent >> >>for scanning the component and how much time it spends to resolve >> >>dependency and performs auto-wiring. >> >> >> >> There are both "pros and cons" for in doing in annotation way or in >> >>XML way. Historically in CloudStack we are doing code-refactoring >> >>quite often, this makes using annotation attractive to CloudStack >> >>developers. >> >>However, >> >> we also need flexibility provided by XML for people to customize >> >>CloudStack after deployment, so historically, CloudStack prefers to >> >>take advantages of both annotation way and XML way. For built-in or >> >>other basic components like DAOs, using annotations can save >> >>developers a lot of typing work. For pluggable components like >> >>Adapters, Network Elements, having them in XML makes more sense. >> >> >> >> As a general guideline, we should keep component as independent of >> >>others as possible, as loosely coupled with other as possible. The >> >>motivation of adopting Spring is for that purpose, to enforce a >> >>consistent way of developing pluggable, unit-testable components. >> >> >> >> However, there is never a perfect solution that can satisfy >> >>everyone's needs, I would prefer to just using auto-wiring and >> >>leaving component definitions all in XML, in this way, component and >> >>a particular container are not tightly coupled (does not necessarily >> >>to be Spring), however, in reality, using @Component with caution can >> >>give developers decent freedom to write component independently >> (they >> >>don't need to remember to edit Java and XML at multiple places and >> >>not everyone likes XML soup). >> >> >> >> A possible solution to combine both the advantages of using >> >>@Component and XML <bean> definitions could be >> >> >> >> Option 1, Using coding convention to reduce the auto-scan scope, for >> >> example, >> >> >> >> All components (Spring component specifically) have to share with the >> >>same java package namespace, for example, >> >>org.apache.cloudstack.component. >> >> overall module/java package structure would look like, Cloud-engine >> >>(module) org.apache.cloudstack.component.XyzMgr >> >> org.apache.cloudstack.component.AbcAdapter >> >> >> >> Cloud-cool-plugin (module) >> >> org.apache.cloudstack.component.CoolMgr >> >> org.apache.cloudstack.component.CoolAdapter >> >> >> >> >> >> >> >> And we only scan org.apache.cloudstack.component. >> >> >> >> We didn't use this approach for the reason that this involves with a >> >> lot of directory refactoring work, and this is too bad for branch >>merges. >> >> >> >> Option 2, Using build-time XML auto-generation >> >> >> >> With this option, developers can continue to use @Component for >> >> meta-programming, we can add a step in build-process that we can >> >> automatically generate the Spring XML file for components that have >> >> been annotated by @Component. >> >> >> >> However, our maven build is already slow now, what we saved in >> >>bootstrapping will have to be paid at build time, so for developers, >> >>this option may still looks slow >> >> >> >> Option 3, Using @Configuration (one more Spring annotation!) >> >> Cloud-server and pluggable module, each can have a per-module Spring >> >> component configuration class (annotated by @Configuration) and we >> >> only scan configuration components at bootstrap. >> >> >> >> Option 3 does not need us to refactor existing directory structure, >> >> and have the flexibility for developers to do module development >> >> independently, as I mentioned early, I'm profiling the Spring >> >> bootstrap process, if it is confirmed that majority of time is spent >> >> in scanning instead of auto-wiring, I'm actually leaning towards >>this option. >> >> >> >> As of whether or not to strictly limit the usage of Spring specific >> >>stuff, >> >> **never** or **ever** to use @Component, I'm not a perfect-ist but a >> >>more practical one, so using @Component only for meta programming >> >>looks fine to me. And In this option, @Component is actually not >> >>necessarily to be defined by Spring, we just happen to borrow it and >> >>that's it. I'm kind of buying the point that with such a powerful >> >>editor like Eclipse, it seems to be much easier for code-refactoring >> >>if things are written in "java" >> >> instead of XML. >> >> >> >> Kelven >> >> >> >> >> >> >> >> On 2/8/13 9:38 PM, "Darren Shepherd" <dar...@godaddy.com> wrote: >> >> >> >>> Frank, >> >>> >> >>> This is probably not the answer you looking for, but I have to just >> >>>throw in my two cents. When should you use @Component? Never. The >> >>>cleanest way to use the Spring container is to *never* "import >> >>>org.springframework". Only bootstrap and obviously spring specific >> >>>code should import spring packages. JSR250 and JSR330 provide >> >>>standards compliant annotations that can be used in place of the >> >>>Spring one's that give most of all the functionality. Refer to >> >>> >> >>>http://static.springsource.org/spring/docs/3.2.x/spring-framework-ref >> >>>ere >> >>>nc >> >>> e/html/beans.html#beans-standard-annotations. >> >>> The standard compliant annotation of @Component would be @Named >> from >> >>> JSR250 (which is included in the JDK at this point). >> >>> >> >>> Regarding when to use @Named and when to register the bean in XML. >> >>>You should never use @Named. I'm sure many will disagree with me but >> >>>past experiences have over and over again shown to me that >> component >> >>>scanning on large scale projects is a bad idea. Ignoring bad >> >>>initialization performance, component scanning ends up introducing >> >>>weird difficult to debug issues when some does something dumb. It is >> >>>better to have a clear and definitive source regarding what is >> >>>registered in your context. >> >>> >> >>> Additionally if you get into context hierarchies (which I hope you >> >>> do, but that is a different topic altogether), component scanning >>blows >> up. >> >>> >> >>> Darren >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> >> >>> -------- Original Message -------- >> >>> Subject: what's rule for using @Component and xml bean file >> >>> From: Frank Zhang <frank.zh...@citrix.com> >> >>> Date: Fri, February 08, 2013 6:39 pm >> >>> To: "cloudstack-dev@incubator.apache.org" >> >>> <cloudstack-dev@incubator.apache.org> >> >>> >> >>> >> >>> I see client/tomcatconf/componentContext.xml.in defining lots of >> >>> beans while I also see many beans use @Component Is there any >> >>> guideline here? >> >> >