cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kelven Yang <kelven.y...@citrix.com>
Subject Re: what's rule for using @Component and xml bean file
Date Mon, 11 Feb 2013 22:23:57 GMT


On 2/11/13 11:39 AM, "Frank Zhang" <Frank.Zhang@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" <darren@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.yang@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" <darren@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.Zhang@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?
>> >>
>


Mime
View raw message