> > On 2/12/13 11:49 AM, "Frank Zhang" <frank.zh...@citrix.com> wrote: > > >The issue here is about convention, no technical reason. > >To construct a big project, especially a project contributed by > >community, a clear and well-understood convention is the key to make > >the project maintainable. > >In my opinion(I may be wrong), the core of convention is > > > > "There should be one-- and preferably only one --obvious way to do > it" > >(from Zen of Python, ironically, I thought Python totally breaks this > >rule) > > +1 > > > > >If we have multiple ways for one goal(again, I disagree with this), it > >will absolutely confuse people new to CloudStack: which way should I > >follow? What's the difference? > >if we don¹t have clear words on this, then people will choose by their > >preference and finally leads to a unmaintainable project. This is why I > >am strongly against having hibernate and DAO in CloudStack, we should > only > >have one persistence framework. > > > > " Special cases aren't special enough to break the rules." > >(Zen of Python again, I really like these rules though I think python > >is not following it well) > > > >Now the question comes to which convention to choose? To our topic is > >bean XML vs @Component. > >I totally understand the reason people like @Component, it's all about > >handy, especially when you write up your first Spring application. > >Except handy, @Component has no advantage comparing to bean XML, > >unfortunately, you have to read verbose and frustrating Spring document > >again and again to grasp its power (I read it three times, it's really > >depressing at beginning because too much puzzling information come to > >you without example). > >People may argue that I don't need this power, but I believe you will, > >as you are constructing a big project, there must be one day you run > >in the situation where these power is for. > > > >However, if our convention is leading to a steep learning curve, it > >will turn developers away from CloudStack as well. The solution is EXAMPLE. > >Simple and clear example is good enough to tell people how to load > >their components without knowing Spring much, if advanced feature is > >needed, they should go Spring documentation anyway. > > > >There is another advantage of bean XML is it enables Declarative > >Programming which is a key for extendibility and flexibility, comparing > >to Imperative Programming we use in our daily job. This is another long > >story, I don't want to make this long thread even longer here. Thanks > >Darren cited an great example recently how declarative REST api > >liberates people from SDK development. > > > >I want to cite an example at last, when I use Vim first time I can > >never imagine an editor so hard to use. But after I was familiar with > >it(I did read the 600+ pages official manual), I will never switch to > >another editor anymore. > > > I think to reduce confusion is very important. Removing @Component all > together sounds good to me. After we used it the last time to generate the > necessary bean definition (either java or XML), we can remove them all. > > However, whether to use pure XML or follow up the similar way of mixing > java/XML that we used before, any more opinions? I know some developers > like the power of having Eclipse to do some smart editing work when you are > refactoring the java code. Either ways, we will get rid of auto-scanning and > only load components based on explicit configuration, this is to solve the > slow bootstrap issue.
I didn't notice JavaConfig feature which is new in Spring 3 before, after reading documents about it, I would suggest XML again. The main reason is it loses lots of power of XML, though it's more handy in some way (to me it's unit test which I think we could adopt javaConfig in some extent). Anther strong reason is avoiding re-compiling when we make some change in Spring configuration. Actually I would suggest us adopting the idea that "allow to change functionality without changing code" in any design, this would make our project stronger , more flexible, and more modular. For example, to disable a component in customer environment for debug purpose, with XML file it's a single line change, with JavaConfig you have to re-compile and deliver some jar file, and binary jar file would not tell you how configuration looks like where XML text does tell > > -Kelven > > > > >> -----Original Message----- > >> From: Edison Su > >> Sent: Tuesday, February 12, 2013 9:44 AM > >> To: Kelven Yang; Frank Zhang; Darren Shepherd > >> Cc: cloudstack-dev@incubator.apache.org > >> Subject: RE: what's rule for using @Component and xml bean file > >> > >> IMHO, if you want configuration(your class needed to be configured by > >>admin, such as all the existing adaptors/manager), use xml, otherwise, > >>use @Component or @named. Switch everything into one style over > >>anther, is really a good idea? For example, I want to my class to be > >>a singleton, and I know for sure, no other body wants to replace and > >>configure it, @Component is just so handy, I don't need to blow up > >>the xml file. > >> > >> > -----Original Message----- > >> > From: Kelven Yang [mailto:kelven.y...@citrix.com] > >> > Sent: Monday, February 11, 2013 2:24 PM > >> > To: Frank Zhang; Darren Shepherd > >> > Cc: cloudstack-dev@incubator.apache.org > >> > Subject: Re: what's rule for using @Component and xml bean file > >> > > >> > > >> > > >> > 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-frame > >> > >> >>>wor > >> > >> >>>k- > >> > >> >>>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? > >> > >> >> > >> > > > >