incubator-cloudstack-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Frank Zhang <Frank.Zh...@citrix.com>
Subject RE: what's rule for using @Component and xml bean file
Date Tue, 12 Feb 2013 19:49:04 GMT
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)

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.

> -----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.yang@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.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-framewor
> > >> >>>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.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