Announcement Announcement Module
Collapse
No announcement yet.
Spring best practices and guidelines Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring best practices and guidelines

    What are your best practices and guidelines with Spring? And why?

    I want to start a discussion about Spring best practices and guidelines. A discussion where people can place their best practices and guidelines with an explanation why this best practice or guideline is good. Others can react on it with additional arguments why this is good, or with arguments why they disagree and maybe propose a better best practice or guideline.

    My goal is: Get a list of all the Spring best practices and guidelines, including all their proís and conís.

    I'll start the discussion by giving some best practices and guidelines.

  • #2
    Always use auto-wiring. (Never ever use explicit wiring.)

    Category: Spring core - configuration
    Argumentation:
    • It saves typing.

    Comment


    • #3
      Bean idís must be in lowerCamelCase.

      Category: Spring core - configuration
      Argumentation:
      • All bean idís in the Spring documentation and samples are in lowerCamelCase.

      Comment


      • #4
        The reference manual has little snips which say, "the Spring team prefer to do it this way"....... I usually find them quite useful.

        BTW, autowiring is voodoo and as such shouldn't be trusted

        Check this out as well.
        http://www.onjava.com/pub/a/onjava/2...practices.html
        Last edited by karldmoore; Dec 7th, 2006, 09:22 AM. Reason: added link

        Comment


        • #5
          Donít place all your beans in one xml file

          Donít place all your beans in one xml file (in large applications).
          Split the configuration in different xml files. Minimal one xml file per architectural layer.

          Category: Spring core Ė configuration

          Argumentation:
          • Long xml files are hard to read.

          Comment


          • #6
            The default injection method to use is: setter injection

            The default injection method to use is: setter injection.

            Category: Spring core

            Argumentation:
            • Almost all the code in the Spring sample applications use setter injection.
            Last edited by Ward Bergmans; Dec 15th, 2006, 03:23 AM. Reason: There was a word missing in the title

            Comment


            • #7
              Every bean must have an id

              Every bean must have an id.
              Always use id to specify the default name of the bean.

              If you need characters in your bean name that are not allowed in the id attribute, then you can provide additional names with the name attribute.
              But always give the bean an id. Because if, in the future, someone wants use the bean with a name following the XML IDREF constraints (and wants to use the id), then that's possible.

              Category: Spring core – configuration

              Argumentation:
              • The id attribute can be validated by a xml parser, the name attribute can’t. And every good xml editor can validate on the id attribute. Because of the validation you will get less typo errors.
              • To limit the risk of an accidental bean overwrite.
                If no id or name attribute is specified, then Spring uses the bean’s class name as the name.
                So if there are two beans of the same type without an id or name attribute specified, they will have the same name. (Note: this is an assumption, I still have to test this to be sure.)
                In some situations one bean can overwrite the other if two beans have the same name.
              Last edited by Ward Bergmans; Dec 21st, 2006, 06:47 AM.

              Comment


              • #8
                Bean Name Space

                Originally posted by Ward Bergmans View Post
                Donít place all your beans in one xml file (in large applications).
                Split the configuration in different xml files. Minimal one xml file per architectural layer.

                Category: Spring core Ė configuration

                Argumentation:
                • Long xml files are hard to read.
                It seems that all the beans in different context files share the same name space (i.e. if you have two beans with the same name, the last context.xml file that is loaded overwrites beans with the same name in previous ones).

                Comment


                • #9
                  Originally posted by martinr View Post
                  It seems that all the beans in different context files share the same name space (i.e. if you have two beans with the same name, the last context.xml file that is loaded overwrites beans with the same name in previous ones).
                  Indeed, useful when unit testing, pain when you can't understand why your code doesn't work.

                  Comment


                  • #10
                    Is there any best practice on how to use a hierarchy of bean factories?

                    I usually put data-source and transaction manager related beans(hibernateSessionFactory, dataSource, lobHandler) into a separate file so that I can replace it for different environments. The list of Hibernate mapping files I keep with the DAO's so that I can reuse it for the different environments.

                    Is there any beest practice on using aliases for switching between different environments?

                    Comment


                    • #11
                      Originally posted by Ward Bergmans View Post
                      Category: Spring core - configuration
                      Argumentation:
                      • It saves typing.
                      I would not recommend using auto wiring in large projects. The chances of unexpected behavior increases and it makes the xml files more difficult to read/understand.
                      Last edited by Zinno1973; Dec 10th, 2006, 02:18 PM.

                      Comment


                      • #12
                        Useful one.

                        Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser will issue an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors are early as possible) if the target bean is in the same XML file.

                        Comment


                        • #13
                          If you need a different configuration to test locally, then overwrite definitions.

                          Originally posted by laenzlinger View Post
                          Is there any best practice on using aliases for switching between different environments?
                          Introduction about our situation:
                          We've got these environments:
                          - Lokaal (Local Developers Machine)
                          - Ontwikkel (Development)
                          - Test (Test ;-))
                          - Acceptatie (Acceptation)
                          - Productie (Production)

                          Our configuration for O, T, A, and P is the same. The configuration for the Local developers machine is different from OTAP.

                          We use CVS as our source code version system.

                          We use Maven 1.0.2 as our build tool.


                          Our best practice:
                          If the configuration is the same for all the environments except for the developers machine, then
                          make (a) separate configuration file(s) with the configuration that is different.
                          Let this different configuration overwrite the definition(s) in the original file(s).
                          Make sure this different configuration will never be placed in the other environments!!!

                          Example of how to achieve this if you use the org.springframework.context.support.ClassPathXmlAp plicationContext:

                          Note: I give every example file below a unique name, so I can easily refer to it.

                          Contents of beanRefContext.xml:

                          <beans>
                          <bean id="aBeanId" class="org.springframework.context.support.ClassPa thXmlApplicationContext">
                          <constructor-arg>
                          <list>
                          <value>/spring/applicationContext-forAllTheEnvironments.xml</value>
                          <value>/spring/applicationContext-local.xml</value>
                          </list>
                          </constructor-arg>
                          <constructor-arg>
                          <ref bean="frameworkApplicationContextId"/>
                          </constructor-arg>
                          </bean>
                          </beans>


                          Some explanation: Beans defined in the config locations (first constructor-arg) overwrite the beans in the parent application context (second constructor-arg).
                          Quote from the JavaDoc of this class "In case of multiple config locations, later bean definitions will override ones defined in earlier loaded files. This can be leveraged to deliberately override certain bean definitions via an extra XML file."

                          This way you can overwrite bean definitions by placing them in applicationContext-local.xml.

                          Contents of the file applicationContext-local.xml:

                          <?xml version="1.0" encoding="UTF-8"?>
                          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
                          <beans>
                          <description>
                          This configuration contains overrides beans and aliases to test the application locally on the developers machine.
                          This configuration should never be placed in production.
                          </description>

                          <!-- In memory DAO's configuration -->
                          <alias alias="blogEntryDao" name="blogEntryDaoMemory" />
                          <alias alias="referralDao" name="referralDaoMemory" />


                          <bean id="managementInfoBean" class="x.y.mockup.ManagementInfoMockup">
                          <description>
                          Bean override of the managementInfoBean with a mockup to be able to test locally.
                          </description>
                          </bean>
                          </beans>


                          applicationContext-local.xml will overwrite the blogEntryDao and referralDao bean with in memory Dao’s and it will overwrite the managementInfoBean with a Mockup.


                          To make sure applicationContext-local.xml is excluded from the build you need to add a exclude resource to the Maven project.xml build tag.

                          Contents of Maven 1.0.2 project.xml:

                          <!-- I left out the first part of the project.xml file contents -->
                          <resources>
                          <resource>
                          <directory>${basedir}src/main/resources</directory>
                          <includes>
                          <include>*.*</include>
                          <include>**/*.*</include>
                          </includes>
                          <excludes>
                          <exclude>.*</exclude>
                          <exclude>spring/applicationContext-local.xml</exclude>
                          </excludes>
                          <filtering>false</filtering>
                          </resource>
                          </resources>
                          </build>
                          </project>


                          Before beanRefContext.xml is committed to CVS "<value>/spring/applicationContext-local.xml</value>" should be removed. But if you forget, there is no problem. If Spring can't find the /spring/applicationContext-local.xml file, Spring doesn't halt. (strange enough Spring doesn't even give an error message). And because /spring/applicationContext-local.xml is excluded from our build Spring can't find it. So this local test configuration will never get into the other environments.

                          Category: Spring core – configuration

                          Argumentation:
                          • If you use the following solution to change the configuration to test locally: Comment out bean definitions in the original configuration file and replace them with bean definitions to test locally. Then you will get the following problems:
                            • You can accidentally place the configuration with the modifications to test locally in CVS. This causes bugs in the environments where this application is deployed.
                            • Configuration files will get longer and harder to read and maintain.
                            • It isn’t easy to comment out configuration parts that have comments in them.
                          Last edited by Ward Bergmans; Dec 22nd, 2006, 01:12 PM. Reason: Rewriten the text to make it a best practice with an example, instead of just an example.

                          Comment


                          • #14
                            Originally posted by Ward Bergmans View Post
                            Donít place all your beans in one xml file (in large applications).
                            Split the configuration in different xml files. Minimal one xml file per architectural layer.

                            Category: Spring core Ė configuration

                            Argumentation:
                            • Long xml files are hard to read.
                            Mmm... we definitely don't want to keep all beans in one file, but I am not sure about breaking down between the service and data access tiers - for the same reasons I don't usually recommend defining Java packages like 'model','service', or 'dao'. Here, in particular, by keeping a service bean and its dao(s) in separate files, you lose the ability to reference by id, and hence the built-in XML validation. Also it's harder to trace the dependencies between beans.

                            Again similar to packaging, my preference would be to split along logical functionality groups. In other words, I see more reason for UserDAO than for ProductDAO to be in the same XML with UserService.

                            All that being said, I do keep all the view definitions separated from the "backend" tiers - so that's indeed some horizontal break-down between the presentation and business tiers. Firstly it's due to that Spring MFC has its own way of loading servlet specific contexts. Secondly it makes it easier to support various deployment schemes and view technologies. (Neither of those applies to the case between service and data access).

                            Comment


                            • #15
                              Originally posted by manifoldronin View Post
                              Here, in particular, by keeping a service bean and its dao(s) in separate files, you lose the ability to reference by id, and hence the built-in XML validation. Also it's harder to trace the dependencies between beans.
                              +1. As you have noted, this makes sense for java packages too.

                              Comment

                              Working...
                              X