博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
写Spring配置文件时的13个最佳实践
阅读量:5883 次
发布时间:2019-06-19

本文共 10863 字,大约阅读时间需要 36 分钟。

  hot3.png

 is a powerful Java application framework, used in a wide range of configuration options. Its best feature if that it provides enterprise services to Plain Old Java Objects (POJOs) called beans. Spring uses  to achieve simplification and increased . Spring beans, dependencies, and the services needed by beans are specified in xml configuration files or annotations. The XML configuration files, however, are verbose and more clean. If not planned and written correctly, it becomes very hard to manage in big projects.

In this article, I will show you 10  for writing spring XML configurations. Some of them may seem more necessary practices rather than best practices, yet I have included them in here because they were highly related to the topic.

Note: Some other factors, such as application design, can impact the XML configuration decisions but I am focusing on the XML configuration’s readability and manageability only.

1) Add a header comment to each configuration file2) Use consistent naming conventions3) No version numbers in schema references4) Prefer setter injection over constructor injection5) Prefer type over index for constructor argument matching6) Use shortcut forms over expanded forms7) Reuse bean definitions as much as possible8) Always use ids as bean identifiers9) Try to avoid autowiring10) Always use classpath prefix11) Always externalize properties12) Use dependency-check at the development phase13) Do not abuse/overuse dependency injection
Lets discuss each of above in detail to make more sense.

1) Add a header comment to each configuration file

I always put more stress on code comments. The same goes for configuration files also. It is always very helpful to add a configuration file header, which summarizes the beans/properties defined in the configuration files.

In spring configuration, you can add comments as adding xml comments or you can use the description element. For example:

1
2
3
4
5
6
7
<beans>
    <description>
        This configuration file will have all beans
        which may be used for controlling transactions.
    </description>
    ...
</beans>

One possible advantage of using the description tag is that some tools may pick up the description from this element to help you in other places.

2) Use consistent naming conventions

This is very important thing that you use same naming across all configuration files. Using clear, descriptive, and consistent name conventions across the project increase the readability of configuration files and make it easy for other developers to avoid some accidental bugs.

For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of EmployeeUpdateDAO would be employeeUpdateDAO. For large projects, you can add the package name as the prefix of the bean ID. e.g. finance.employeeUpdateDAO.

3) No version numbers in schema references

I have also pointed out this feature earlier in previous post. I am again including it because it is essential and beneficial in long term specially to reduce maintainbility. To refresh your memory, specifying version number in bean configuration files for referenced schemas are not mandatory at all, and you can omit it. If fact, you should omit it all the time.

Spring automatically picks the highest version available from the project dependencies (jars). Also, as the project evolves and the Spring version will be updated, we won’t have to maintain all the XML config files to see the new features.

Read More: 

A sample example will be like this:

1
2
3
4
5
6
7
8
9
10
11
12
<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns=" "
  xmlns:xsi=" "
  xmlns:context=" "
  xsi:schemaLocation="
  
  
   ">
  
  <!-- Other bean definitions-->
    
</beans>

4) Prefer setter injection over constructor injection

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

1
2
3
4
5
6
7
8
9
<!-- Constructor injection -->
<beanid="employeeDAO"  class="com.howtodoinjava.dao.EmployeeDAO">
    <constructor-argref="datasource"/>
</bean>
 
<!-- Setter injection -->
<beanid="employeeDAO"class="com.howtodoinjava.dao.EmployeeDAO">
    <propertyname="datasource" ref="datasource">
</bean>

Constructor injection can provide the cheapest thread safety possible i.e. . Also it guarantees that object will not be handed over to other beans without complete initialization.

Setter injection provides much desired capability i.e. flexibility or maintainability. If there are multiple attributes to set in a bean, then creating a long list of parameters to constructor is not good idea. Also, if is possible that some of the attributes might be optional.

Prefer flexibility. For immutability or thread safety, follow other programming rules.

Read More: 

5) Prefer type over index for constructor argument matching in Constructor injection

Better to avoid constructor injection and prefer to use setter injection for dependency injection. But, if you have an absolute requirement to use constructor injection then always prefer parameter matching based on type rather than index.

1
2
3
4
5
6
7
8
9
10
11
<!-- Index based constructor injection -->
<beanid="employeeDAO"class="com.howtodoinjava.EmployeeDAO">
    <constructor-argindex="0"value="rest"/>
    <constructor-argindex="1"value="8080"/>
</bean>
 
<!-- Type based constructor injection -->
<beanid="employeeDAO"class="com.howtodoinjava.EmployeeDAO">
    <constructor-argtype="java.lang.String"value="rest"/>
    <constructor-argtype="int"value="8080"/>
</bean>

As you can see that type based argument passing is more readable and less error prone. But, anytime there is any ambiguity in type based argument passing, go to index based argument passing without hesitation.

6) Use shortcut forms over expanded forms

Spring bean configuration semantics allow two forms for specifying property values and other bean references. One is expanded and other is shorter form. Prefer shorter version.

1
2
3
4
5
6
7
8
9
10
11
12
<!-- Expanded version -->
<beanid="employeeDAO"class="com.howtodoinjava.dao.EmployeeDAO">
    <propertyname="datasource">
        <refbean="datasource"></ref>
        <value>datasource</value>
     </property>
</bean>
 
<!-- Shorter/shortcut version -->
<beanid="employeeDAO"class="com.howtodoinjava.dao.EmployeeDAO">
    <propertyname="datasource" ref="datasource"value="datasource">
</bean>

7) Reuse bean definitions as much as possible

Spring provides a very useful capability which you should use extensively in your project and i.e. bean definition re-usability. Here I am not talking about bean references for setter injection. Rather I am pointing out the bean definition re-use in constructing other beans.

Take an example of datasource definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
<beanid="abstractDataSource"class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"
    p:driverClassName="${jdbc.driverClassName}"
    p:username="${jdbc.username}"
    p:password="${jdbc.password}"/>
 
<beanid="concreteDataSourceOne"
    parent="abstractDataSource"
    p:url="${jdbc.databaseurlOne}"/>
  
<beanid="concreteDataSourceTwo"
    parent="abstractDataSource"
    p:url="${jdbc.databaseurlTwo}"/>

Read complete configuration example here: 

8) Always use ids as bean identifiers

Spring allows two types of identifiers for a bean. Using attribute “id” or by “name”. You should always choose attribute id over name. Usually it does neither increase readability nor benefit any performance scenario. It is just industry standard practice which all fellow developers are following worldwide and even in your team.

Just don’t be odd man out here.

9) Try to avoid autowiring

Autowiring is a great feature if you can manage it in long term. Usually it is beneficial if you project is having very few beans and you can almost remember them all in your memory as well.

As soon as project gets bigger, autowiring starts creating trouble in identifying correct dependency to use. The main drawback, I find is not to have a overview of whole system binded together. This is where spring configuration files win. They can represent the whole system to any new guy in couple of minutes.

Also, when you start debugging some complex issues then all information present in one place in configuration files, actually helps a lot. Autowiring makes debugging harder.

Read More: 

10) Always use classpath prefix

When importing resources, XML config, properties, etc. Always use the classpath: or classpath*: prefix. This provides consistency and clarity to the location of the resource. Not every feature of Spring behaves the same, classpath: guarantees consistency.

The classpath is determined by the build tool and IDE. Usually this is src/main/java for java code, src/main/resources for non-java dependencies and for tests, src/test/java for java code and src/test/resources for non-java resources.

1
2
<!-- Always use classpath: prefix-->
<importresource="classpath:/META-INF/spring/applicationContext-security.xml"/>

11) Always externalize properties

Often there are multiple configuration parameters related to runtime of application. They are passed to bean definitions in bean configuration context file. DO not hard code them in config file. Instead externalize them to some properties file(s).

Better group them in separate files based on their usage or module i.e. all JDBC datasource related properties in jdbc.propertiesfile.

1
2
3
4
5
<beanid="abstractDataSource"class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"
        p:driverClassName="${jdbc.driverClassName}"
        p:username="${jdbc.username}"
        p:password="${jdbc.password}"/>

and properties file

1
2
3
4
5
/*  file://jdbc.properties */
 
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=password

12) Use dependency-check at the development phase

You should mostly set the dependency-check attribute on a bean definition to simple, objects, or all (default value is none i.e. no checking), so that the container can do explicit 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.

1
2
3
4
5
6
<beanid="abstractDataSource"class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close"
    p:driverClassName="${jdbc.driverClassName}"
    p:username="${jdbc.username}"
    p:password="${jdbc.password}"
    dependency-check="all"/>

In above given example, the container will ensure that all properties/parameters to datasource are set in application initialization time itself.

13) Do not abuse/overuse dependency injection

Finally, please do not abuse the motive behind introducing . Java provide “new” keyword to create new objects. Use this wonderful keyword where DI is not necessary e.g. DTO objects. Don’t try to play smarter. Just follow the basics.

Drop me a comment if you feel otherwise on any of above points.

Happy Learning !!

转载于:https://my.oschina.net/leyou/blog/468129

你可能感兴趣的文章
Linux 多线程环境下 进程线程终止函数小结
查看>>
模块手动执行和模块导入执行
查看>>
进制转换
查看>>
UA池和代理池在scrapy中的应用
查看>>
form组件
查看>>
List的深度copy和浅度拷贝
查看>>
c语言 变量的存储类别以及对应的内存分配?
查看>>
CCF认证历年试题集
查看>>
九章算术卷第九 句股
查看>>
从更高点看软件开发的侧重点
查看>>
01.变量和字符编码
查看>>
遗传算法求系统组合
查看>>
股指的趋势持续研究(Hurst指数)
查看>>
前端上传图片 base64转二进制上传
查看>>
结构体
查看>>
ROS主题发布订阅
查看>>
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream
查看>>
python基础,python第二课
查看>>
RabbitMQ~一些术语和最消息的生产
查看>>
Redis学习笔记~把redis放在DATA层,作为一种数据源,我认为更合理,也更符合我的面向对象原则...
查看>>