`
hlbng
  • 浏览: 177526 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Twelve Best Practices For Spring XML Configuration

阅读更多

Spring is a powerful Java application framework, used in a wide range of Java applications. It provides enterprise services to Plain Old Java Objects (POJOs). Spring uses dependency injection to achieve simplification and increase testability. Spring beans, dependencies, and the services needed by beans are specified in configuration files, which are typically in an XML format. The XML configuration files, however, are verbose and unwieldy. They can become hard to read and manage when you are working on a large project where many Spring beans are defined.

In this article, I will show you 12 best practices for Spring XML configurations. Some of them are more necessary practices than best practices. Note that other factors, such as domain model design, can impact the XML configuration, but this article focuses on the XML configuration's readability and manageability.

1. Avoid using autowiring

Spring can autowire dependencies through introspection of the bean classes so that you do not have to explicitly specify the bean properties or constructor arguments. Bean properties can be autowired either by property names or matching types. Constructor arguments can be autowired by matching types. You can even specify the autodetect autowiring mode, which lets Spring choose an appropriate mechanism. As an example, consider the following:

    <bean id="orderService"
        class="com.lizjason.spring.OrderService"
        autowire="byName"/>

The property names of the OrderService class are used to match a bean instance in the container. Autowiring can potentially save some typing and reduce clutter. However, you should not use it in real-world projects because it sacrifices the explicitness and maintainability of the configurations. Many tutorials and presentations tout autowiring as a cool feature in Spring without mentioning this implication. In my opinion, like object-pooling in Spring, it is more a marketing feature. It seems like a good idea to make the XML configuration file smaller, but this will actually increase the complexity down the road, especially when you are working on a large project where many beans are defined. Spring allows you mix autowiring and explicit wiring, but the inconsistency will make the XML configurations even more confusing.

2. Use naming conventions

This is the same philosophy as for Java code. Using clear, descriptive, and consistent name conventions across the project is very helpful for developers to understand the XML configurations. For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of OrderServiceDAO would be orderServiceDAO.For large projects, you can add the package name as the prefix of the bean ID.

3. Use shortcut forms

The shortcut form is less verbose, since it moves property values and references from child elements into attributes. For example, the following:

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName">
            <value>lizjason</value>
        </property>
        <constructor-arg>
            <ref bean="orderDAO">
        </constructor-arg>
    </bean>

can be rewritten in the shortcut form as:

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

The shortcut form has been available since version 1.2. Note that there is no shortcut form for <ref local="...">.

The shortcut form not only saves you some typing, but also makes the XML configuration files less cluttered. It can noticeably improve readability when many beans are defined in a configuration file.

4. Prefer type over index for constructor argument matching

Spring allows you to use a zero-based index to solve the ambiguity problem when a constructor has more than one arguments of the same type, or value tags are used. For example, instead of:

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg index="0" value="lizjason"/>
        <constructor-arg index="1" value="100"/>
    </bean>

It is better to use the type attribute like this:

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg type="java.lang.String"
            value="lizjason"/>
        <constructor-arg type="int" value="100"/>
    </bean>

Using index is somewhat less verbose, but it is more error-prone and hard to read compared to using the type attribute. You should only use index when there is an ambiguity problem in the constructor arguments.

5. Reuse bean definitions, if possible

Spring offers an inheritance-like mechanism to reduce the duplication of configuration information and make the XML configuration simpler. A child bean definition can inherit configuration information from its parent bean, which essentially serves as a template for the child beans. This is a must-use feature for large projects. All you need to do is to specify abstract=true for the parent bean, and the parent reference in the child bean. For example:

    <bean id="abstractService" abstract="true"
        class="com.lizjason.spring.AbstractService">
        <property name="companyName"
            value="lizjason"/>
    </bean>

    <bean id="shippingService"
        parent="abstractService"
        class="com.lizjason.spring.ShippingService">
        <property name="shippedBy" value="lizjason"/>
    </bean>

The shippingService bean inherits the value lizjason for the companyName property from the abstractService bean. Note that if you do not specify a class or factory method for a bean definition, the bean is implicitly abstract.

6. Prefer assembling bean definitions through ApplicationContext over imports

Like imports in Ant scripts, Spring import elements are useful for assembling modularized bean definitions. For example:

    <beans>
        <import resource="billingServices.xml"/>
        <import resource="shippingServices.xml"/>
        <bean id="orderService"
            class="com.lizjason.spring.OrderService"/>
    <beans>

However, instead of pre-assembling them in the XML configurations using imports, it is more flexible to configure them through the ApplicationContext. Using ApplicationContext also makes the XML configurations easy to manage. You can pass an array of bean definitions to the ApplicationContext constructor as follows:

    String[] serviceResources =
        {"orderServices.xml",
        "billingServices.xml",
        "shippingServices.xml"};
    ApplicationContext orderServiceContext = new
        ClassPathXmlApplicationContext(serviceResources);

7. Use ids as bean identifiers

You can specify either an id or name as the bean identifier. Using ids will not increase readability, but it can leverage the XML parser to validate the bean references. If ids cannot be used due to XML IDREF constraints, you can use names as the bean identifiers. The issue with XML IDREF constraints is that the id must begin with a letter (or one of a few punctuation characters defined in the XML specification) followed by letters, digits, hyphens, underscores, colons, or full stops. In reality, it is very rare to run into the XML IDREF constraint problem.

 

8. Use dependency-check at the development phase

You can set the dependency-check attribute on a bean definition to a value other than the default none, such as simple, objects, or all, so that the container can do the dependency validation for you. It is useful when all of the properties (or certain categories of properties) of a bean must be set explicitly, or via autowiring.

 

    <bean id="orderService"
        class="com.lizjason.spring.OrderService"
        dependency-check="objects">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

In this example, the container will ensure that properties that are not primitives or collections are set for the orderService bean. It is possible to enable the default dependency check for all of the beans, but this feature is rarely used because there can be beans with properties that don't need to be set.

9. Add a header comment to each configuration file

It is preferred to use descriptive ids and names instead of inline comments in the XML configuration files. In addition, it is helpful to add a configuration file header, which summarizes the beans defined in the file. Alternatively, you can add descriptions to the description element. For example:

<!-- sidebar begins --><!-- don't move sidebars --><!-- sidebar ends -->

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

One advantage of using the description element is that it is easy to for tools to pick up the description from this element.

10. Communicate with team members for changes

When you are refactoring Java source code, you need to make sure to update the configuration files accordingly and notify team members. The XML configurations are still code, and they are critical parts of the application, but they are hard to read and maintain. Most of the time, you need to read both the XML configurations and Java source code to figure out what is going on.

11. Prefer setter injection over constructor injection

Spring provides three types of dependency injection: constructor injection, setter injection, and method injection. Typically we only use the first two types.

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <constructor-arg ref="orderDAO"/>
    </bean>

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <property name="billingDAO"
            ref="billingDAO">
    </bean>

In this example, the orderService bean uses constructor injection, while the BillingService bean uses setter injection. Constructor injection can ensure that a bean cannot be constructed in an invalid state, but setter injection is more flexible and manageable, especially when the class has multiple properties and some of them are optional.

12. Do not abuse dependency injection

As the last point, Spring ApplicationContext can create Java objects for you, but not all Java objects should be created through dependency injection. As an example, domain objects should not be created through ApplicationContext. Spring is an excellent framework, but, as far as the readability and manageability are concerned, the XML-based configuration can become an issue when many beans are defined. Overuse of dependency injection will make the XML configuration more complicated and bloated. Remember, with powerful IDEs, such as Eclipse and IntelliJ, Java code is much easier to read, maintain, and manage than XML files!

Conclusion

XML is the prevailing format for Spring configurations. XML-based configuration can become verbose and unwieldy when many beans are defined. Spring provides a rich set of configuration options. Appropriately using some of the options can make the XML configurations less cluttered, but other options, like autowiring, may reduce readability and maintainability. Following good practices discussed in the article may help you to create clean and readable XML configuration files!

 

<!-- article_sidebar2.view begins --><!--ONJava MPU Ad -->

分享到:
评论

相关推荐

    Twelve

    标题“Twelve”可能指的是一个特定的字体设计或者字体系列,通常在字体设计中,命名可能会包含数字以区分不同的风格或版本。在这个场景下,“Twelve”可能是一个具有独特视觉特征的字体,可能是由12个基本元素或者...

    Twelve-month cash flow.xls

    Twelve-month cash flow.xls

    年Unit 3 Spring begins from March课堂练习题及答案陕旅精选.doc

    【标题与描述分析】:这个文档标题"年Unit 3 Spring begins from March课堂练习题及答案陕旅精选.doc"表明这是一份与教育相关的材料,具体是关于学习春季(Spring)开始于三月(March)的英语课堂练习题目及答案。...

    Twelve Ton Goldfish

    标题“Twelve Ton Goldfish”可能是指一个设计项目或者一种艺术风格,但在这个上下文中,它与“字体”标签关联,暗示我们关注的是一个特定的字体设计。这个字体可能命名为“Twelve Ton Goldfish”,或者它是围绕这个...

    CAP Twelve Years Later——How the 'Rules' Have Changed

    在IT行业中,CAP定理是分布式系统设计中的一个基础理论,由计算机科学家Eric Brewer提出。这个理论在2012年被再次讨论,探讨了在技术发展的十二年后,“规则”如何变化。CAP定理,全称是Consistency、Availability、...

    CAP Twelve Years Later:How the "Rules" Have Changed.pdf

    The CAP theorem asserts that any net- worked shared-data system can have only two of three desirable properties. How- ever, by explicitly handling partitions, designers can optimize consistency and ...

    Twelve(1).java

    Twelve(1).java

    外研一起小学英语五下《Module2Unit 2 Lunch is usually at half past twelve.》w

    在语言知识目标方面,学生需要能够识别并准确使用"usually"这个词,以及理解并诵读目标语句"Lunch is usually at half past twelve"。这涉及到时间表达和频率副词的运用,"usually"表示通常,常用来描述日常发生的...

    Twelve Month Sales Forecast.xls

    Twelve Month Sales Forecast.xls

    DevOps For The Modern Enterprise-IT Revolution Press(2018).epub

    automation across the software delivery life cycle (SDLC), and leveraging modern architecture patterns like cloud native application, twelve-factor applications, and microservices. Yet if we look ...

    twelve.ino

    twelve.ino

    Effects on first-grade promotion practices of a program for the prevention of learning disabilities

    Effects on first-grade promotion practices of a program for the prevention of learning disabilities Psychology in the Schools Volume 21 . October. 1984 EFFECTS ON FIRST-GRADE PROMOTION PRACTICES ...

    cdc.rar_pubgmonbing_religiousrwz_twelve7mb_慢病_慢病管理系统

    "cdc"通常指的是疾病控制与预防中心(Centers for Disease Control and Prevention),在IT领域可能指代数据收集和疾病管理的相关系统。"pubgmonbing"可能是某种命名规则或者错误拼写,不太明确其具体含义。...

    Twelve month profit and loss projection.xls

    Twelve month profit and loss projection.xls

    小贝程序员生活\课件\java\javaclass\twelve lesson.rar

    这个列表表明压缩包内只有一个文件,名为“twelve lesson”,这可能是一个综合性的文件,如PDF文档、PPT演示文稿或者包含多个子目录和文件的结构,详细解释Java类和对象的概念,如何定义它们,如何创建对象,以及...

    Twelve Ton Fishstick

    "Twelve Ton Fishstick" 是一个独特的字体设计项目,它可能代表了一种创新或艺术性的字体样式。在IT行业中,字体扮演着至关重要的角色,它们不仅用于文本的呈现,还影响着用户对网站、应用程序或者设计作品的第一...

    CAP Twelve Years Later: How the“Rules” Have Changed

    ### CAP十二年后:规则如何变迁 #### 背景与意义 随着分布式系统的不断发展与进步,CAP 定理(Consistency, Availability, Partition tolerance)在系统设计中的地位日益凸显。CAP 定理由埃里克·布鲁尔(Eric ...

    Twelve Ton Sushi

    "Twelve Ton Sushi" 是一个独特的字体设计,它的名字可能来源于日本料理中的寿司,暗示着这个字体如同精致的寿司一般,虽然轻巧但充满质感。在IT行业中,字体设计是用户界面(UI)和用户体验(UX)设计的重要组成...

    Twelve-Lead Electrocardiography.pdf

    通过以上内容,可以看出《Twelve-Lead Electrocardiography》这本书不仅提供了十二导联心电图的基础理论知识,还深入探讨了如何有效地利用这些知识进行临床实践,对于医疗工作者来说具有很高的参考价值。

    twelve_de_eleven-bank_project-master.zip

    在这个名为"twelve_de_eleven-bank_project-master.zip"的项目中,开发者构建了一个简易的银行账户管理平台,用户可以进行存款、取款和转账等基本操作。这个项目主要基于Java编程语言和MySQL数据库系统,两者都是IT...

Global site tag (gtag.js) - Google Analytics