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

  • #16
    But especially for the packages I like the separation in layers.
    You can assure that nothing relies on implementation details (as long as you don't make it public).

    Jörg

    Comment


    • #17
      Originally posted by Jörg Heinicke View Post
      But especially for the packages I like the separation in layers.
      You can assure that nothing relies on implementation details (as long as you don't make it public).
      Hi Jörg,

      What do you mean exactly? Do you propose to put the classes for each layer into a separate package like in the jpetstore sample?

      I used this approach before and put the the corresponding bean definitions into the classpath close to those classes - with the disadvantages mentioned below.

      Both organisations have advantages and disadvantages, depending on what level of (de-)coupling you want to achieve. For example if you need to provide different data-access implementations it might be better to have the data-access layer in a separate file so that it is easier to can exange it.

      On the other hand if it is more important to deliver complete sub-components along functional borders it might be better to keep the whole component defintion together.

      Comment


      • #18
        Originally posted by laenzlinger View Post
        What do you mean exactly? Do you propose to put the classes for each layer into a separate package like in the jpetstore sample?
        That was only meant on the Java packages level without considering Spring configs at all. I have exactly the packages 'model', 'service' and 'dao' as mentioned by manifoldronin.

        I wonder how often it's possible to 'deliver complete sub-components along functional borders'. At least for my applications there is rarely a 1:1-relationship between classes in the different layers. This seems to be mostly only the case for pure CRUD, doesn't it?

        Regards
        Jörg

        Comment


        • #19
          Use parent bean if beans must have the same value(s), or if it saves typing.

          Use parent bean if the same values must be injected in multiple beans, or if it saves typing.

          Category: Spring core – configuration

          A child bean definition is a bean definition which inherits configuration data from a parent definition.

          A parent bean definition is a "template" with configuration information that can be inherited. The parent bean can be marked abstract (with abstract="true") to prevent it from being instantiated.

          See the Spring Reference Manual, paragraph 3.6. Bean definition inheritance for more information.

          Example of bean definition inheritance:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
          <beans>
          <description>
          Spring Web MVC Dispatcher Servlet configuration.
          </description>

          <!-- *********************** -->
          <!-- Application controllers -->
          <!-- *********************** -->

          <!-- abstract parent bean with configuration that needs to be the same for all the controllers -->
          <bean id="abstractController" abstract="true">
          <property name="blogService" ref="blogService" />
          <property name="administrationService" ref="administrationService" />
          </bean>

          <bean id="overviewController" name="/overview.htm" parent="abstractController" class="x.y.z.web.controllers.OverviewController">
          <property name="viewName" value="overview" />
          </bean>

          <bean id="showController" name="/show.htm" parent="abstractController" class="x.y.z.web.controllers.ShowBlogEntryControll er">
          <property name="viewName" value="show" />
          </bean>

          <!-- The add and edit controller -->
          <bean id="addAndEditController" name="/edit.htm" parent="abstractController" class="x.y.z.web.controllers.AddAndEditController" >
          <property name="formView" value="edit" />
          <property name="successView" value="redirect:overview.htm" />
          <property name="validator">
          <bean class="x.y.z.validators.BlogEntryValidator" />
          </property>
          </bean>

          <bean id="saveController" name="/save.htm" parent="abstractController" class="x.y.z.web.controllers.SaveController">
          <property name="viewName" value="save" />
          </bean>

          <!-- The DeleteBlogEntryController is a ThrowAwayController, there singleton needs to be "false" -->
          <bean name="/delete.htm" parent="abstractController" class="x.y.z.web.controllers.DeleteBlogEntryContro ller" singleton="false" />

          <bean id="rssController" name="/rss.htm" parent="abstractController" class="x.y.z.web.controllers.RSSController">
          <property name="view" ref="rssView" />
          </bean>

          <bean id="pdfController" name="/showPDF.htm" parent="abstractController" class="x.y.z.web.controllers.PdfController">
          <property name="view" ref="pdfView" />
          </bean>

          <!-- ...I left out the rest of the content of my configuration file. The above is (more than) enough to demonstrate bean definition inheritance ... -->


          Argumentation:
          • If all beans must have the same values injected and the values change, then you only have to change the parent bean definition. This way all the child beans (that don’t overwrite a value) will have the new values. This saves typing and prevents errors (like forgetting to change the values for one bean.)
          • If you got a list of property value pairs that are injected in a lot of beans, then you will get long configuration files (which are hard to read). Bean inheritance can prevent this.
          • Writing the same property value pairs over and over again takes time. With bean inheritance this time can be reduced.
          • Templating prevents configuration duplication. Duplication - whether in configuration or code - is bad and should be minimized.
          Last edited by Ward Bergmans; Dec 14th, 2006, 09:35 AM. Reason: Added an extra argument: Templating prevents configuration duplication.

          Comment


          • #20
            Templating beans can be very useful, this was true pre 2.0 with a TransactionProxyFactoryBean.

            Comment


            • #21
              Originally posted by karldmoore View Post
              Templating beans can be very useful, this was true pre 2.0 with a TransactionProxyFactoryBean.
              Why is it not very usefull anymore since Spring 2.0 with the TransactionProxyFactoryBean?

              I don't understand how the TransactionProxyFactoryBean can provide a better best practice than templating... Can you please give some more explanation?

              Comment


              • #22
                Originally posted by Ward Bergmans View Post
                Why is it not very usefull anymore since Spring 2.0 with the TransactionProxyFactoryBean?

                I don't understand how the TransactionProxyFactoryBean can provide a better best practice than templating... Can you please give some more explanation?
                What I'm saying is, pre 2.0 you had to use TransactionProxyFactoryBean for declarative transactions. To cut down the XML templating provided a very nice abstraction. In 2.0 there are the new namespaces which cut down the need for lots of XML. I do *still* use templating though on other things.

                Where is TransactionProxyFactoryBean?

                Declarative transaction configuration in versions of Spring 2.0 and above differs considerably from previous versions of Spring. The main difference is that there is no longer any need to configure TransactionProxyFactoryBean beans.

                The old, pre-Spring 2.0 configuration style is still 100% valid configuration; under the covers think of the new <tx:tags/> as simply defining TransactionProxyFactoryBean beans on your behalf.
                http://www.springframework.org/docs/...on-declarative

                Comment


                • #23
                  ...pre 2.0 you had to use TransactionProxyFactoryBean for declarative transactions. To cut down the XML templating provided a very nice abstraction. In 2.0 there are the new namespaces which cut down the need for lots of XML. I do *still* use templating though on other things.
                  I do agree. Spring 2 schema for transaction and aop configuration make transaction management a powerful and easy to configure technology.
                  Having said that, if possible, I prefer DTD over schema as w3c schemata does not support general entities. The latter make XML more readable and add to validation
                  Code:
                  <?xml version="1.0" encoding="UTF-8"?>
                  <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                          "http://www.springframework.org/dtd/spring-beans-2.0.dtd"[
                   <!ENTITY LocalContainerEntityManagerFactoryBean "org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                   <!ENTITY HibernateJpaVendorAdapter "org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                   
                   <!ENTITY JpaTemplate "org.springframework.orm.jpa.JpaTemplate">
                   <!ENTITY JdbcTemplate "org.springframework.jdbc.core.JdbcTemplate">
                   <!ENTITY NamedParameterJdbcTemplate "org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
                   <!ENTITY persistenceXmlLocation "com/arno/net/test/jdbc/jpa/META-INF/persistence.xml">
                  ...
                    ]>
                  <beans default-init-method="init">
                      <bean
                          id="entityManagerFactory"
                          class="&LocalContainerEntityManagerFactoryBean;">
                          <property
                              name="dataSource"
                              ref="dataSource" />
                          <property
                              name="persistenceXmlLocation"
                              value="&persistenceXmlLocation;" />
                          <property name="jpaVendorAdapter">
                              <bean class="&HibernateJpaVendorAdapter;" />
                          </property>
                      </bean>
                      <bean
                          id="jpaTemplate"
                          class="&JpaTemplate;">
                          <constructor-arg ref="entityManagerFactory" />
                      </bean>
                      <bean
                          name="jdbcTemplate"
                          class="&JdbcTemplate;">
                          <property
                              name="dataSource"
                              ref="dataSource" />
                      </bean>
                      <bean
                          id="namedParameterJdbcTemplate"
                          class="&NamedParameterJdbcTemplate;">
                          <constructor-arg ref="jdbcTemplate" />
                      </bean>
                  ...
                  </beans>

                  Comment


                  • #24
                    Originally posted by Jörg Heinicke View Post
                    I wonder how often it's possible to 'deliver complete sub-components along functional borders'. At least for my applications there is rarely a 1:1-relationship between classes in the different layers. This seems to be mostly only the case for pure CRUD, doesn't it?
                    I don't think we necessarily have to have a 1:1 relationship between layers in order to organize classes into functional groups. I wasn't suggesting to build up a wall between the functional packages. They can still depend on each other.

                    And that's precisely one advantage of the functionality-oriented packaging approach - the dependency "arrows" between packages truely reflect the functional dependencies, and closely resemble the dependencies between use cases and functionalities. On the other hand, the "cluster of arrows" shooting from 'service' to 'dao' (which often look like a cold war style massive missile attack, just kidding ) doesn't tell us anything more than "the service tier relies on the dao tier." OK, but, duh...

                    Comment


                    • #25
                      Originally posted by Ward Bergmans View Post
                      The default injection method to use is: setter injection.
                      But that doesn’t mean you should always use setter injection.
                      Don’t use setter injection if it conflicts with one of the following best practices. (See my next posts for more information about the best practices in the list below.)
                      • Use constructor injection to set required properties that don’t have default values.
                      • Use constructor injection for properties that must be immutable or for properties that may not be changed by others.
                      • Use constructor injection for properties that must be set in a certain order.

                      Comment


                      • #26
                        Use constructor injection to set required properties that don’t have default values.

                        Use constructor injection to set required properties that don’t have default values.

                        (Note: With default values I mean: functionally meaningful default values. Not the Java default values, like 'null' for an Object and 0 for an int.)

                        Provide default values for properties when possible.

                        Only provide (a) constructor(s) that at least have arguments to set all the required properties that don’t have default values.

                        Category: Spring core

                        Argumentation:
                        • With this best practice you can be sure that the required properties are set when the object is initialized. It is impossible to forget to a set a property that is required but doesn’t have a default value, because then it’s impossible to construct the object.
                        • If you only use setter injection you can get the following problem in multithreaded applications:
                          • Thread 1: creates the object.
                          • Thread 2: uses the object.
                          • Thread 1: sets the required properties that don’t have default values.
                          Then thread 2 uses an invalid object, because the required properties aren’t set yet. This best practice prevents that problem.
                        • If you would not use the Spring framework and you would design a class which has required properties that don’t have default values. You would probably give the class (a) constructor(s) that at least have arguments to set all the required properties that don’t have default values.
                          Why would you change that design when you use the Spring framework???
                          One of the good things about Spring is: it is non-invasive (at least, you can use it in a non-invasive way.) The good thing about a non-invasive framework is that it easier to replace than a invasive framework. So don’t use frameworks in an invasive way without a good reason.
                          If you only provide a no-argument constructor to be able to use Spring setter-injection, than you use Spring in an invasive way.
                          Conclusion: Don’t create a no-argument constructor if the only reason to do so is to be able to use Springs setter injection.
                        • Using setter injection for the rest of the properties is preferred
                          • to prevent long argument lists for constructors.
                          • to prevent argument lists for constructors with arguments of the same type.
                          • to be able to use reflection. (In a compiled class file, constructor argument names are not retained. But setter and getter names are visible for reflection.)
                        • Note: If you get a long argument list for constructors, this can be a sign that you’ve created a class that’s over busy and should be split.
                        • See the article "Inversion of Control Containers and the Dependency Injection pattern" by Martin Fowler for more information about why you should use constructor injection.

                        Comment


                        • #27
                          Use constructor injection if it is not allowed (for others) to change the property.

                          Use constructor injection for properties that must be immutable or for properties that may not be changed by others.
                          Use constructor injection if there is no reason to make a public setter except to be able to use Spring setter-injection.

                          Category: Spring core

                          Argumentation:
                          • I’ve said it before, and I’ll say it again. Don’t let a framework be invasive without a good reason.
                            So: Don’t provide public setters for properties if the only reason to do so is to be able to use Springs setter-injection.
                          • If the user of a class isn’t allowed to change a property value, then you should not provide setters to change this value. If you do, the property can be changed and one day probably will be changed. (How long will it take to find the cause of the failures this will cause?)
                          • If a property must be immutable, you must not provide a setter to change it. You must make the property final and set it during construction time. (Or, to be more precise: make sure that it is set before the construction of the instance is finished).

                          Comment


                          • #28
                            Use constructor injection for properties that must be set in a certain order.

                            Use constructor injection for properties that must be set in a certain order.

                            Only provide (a) constructor(s) that guarantee(s) that the properties are set in the required order.

                            Category: Spring core

                            Argumentation:
                            • If properties must be set in a certain order, you would normally design you class like this: the class will only have constructors that make sure the properties are set in the right order.
                              Why would you change that design when you use the Spring framework???
                              The whole idea behind Spring is that you can design your classes how you like and have Spring work for you, not the other way around.

                            Comment


                            • #29
                              Add a description comment to each configuration file.

                              Add a description comment to each configuration file, which explains the reason for this file and summarizes the beans defined in it.

                              For example:

                              <beans>
                              <description>
                              This file defines billing service related beans and it depends on baseServices.xml, which provides service bean templates...
                              </description>
                              ...
                              </beans>


                              Category: Spring core – configuration

                              Argumentation:
                              • Documentation in code is easier to read and maintain than documentation in separate documents.
                              • One advantage of using the description element is that it is easy for tools to pick up the description from this element.
                              Last edited by Ward Bergmans; Dec 22nd, 2006, 02:48 AM. Reason: corrected a typo

                              Comment


                              • #30
                                Place bean documentation in the description tag.

                                Place bean documentation in the description tag.

                                For example:

                                <bean id="aBean" class="x.y.z.AClass">
                                <description>
                                Bla, bla, bla...
                                </description>
                                ...
                                </bean>


                                Category: Spring core – configuration

                                Argumentation:
                                • One advantage of using the description element is that it is easy for tools to pick up the description from this element.
                                Last edited by Ward Bergmans; Dec 18th, 2006, 04:09 AM.

                                Comment

                                Working...
                                X