Skip to main content

Spring Best Pratices

Best Practices For Spring XML Configurations
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.
Some of best practices for Spring XML configurations can be followed are  as below. Some of them are more necessary practices than best practices.

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.
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 EmployeeServiceDAO would be employeeServiceDAO.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="employeeService"
        class="com..spring.EmployeeService ">
        <property name="orgName">
            <value>mycompany</value>
        </property> 
        <constructor-arg>
            <ref bean="employeeDAO">
        </constructor-arg>
    </bean>
can be rewritten in the shortcut form as:
    <bean id="employeeService"
        class="com.spring.EmployeeService">
        <property name="orgName"
            value="mycompany"/>
        <constructor-arg ref="employeeDAO"/>
    </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="employeeService"
        class="com.spring.BillingService">
        <constructor-arg index="0" value="myOrg"/>
        <constructor-arg index="1" value="100"/>
    </bean>
It is better to use the type attribute like this:
    <bean id="billingService"
        class="com..spring.BillingService">
        <constructor-arg type="java.lang.String" 
            value=" myOrg "/>
        <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.spring.AbstractService">
        <property name="companyName"
            value="xyz"/>
    </bean>
 
    <bean id="shippingService"
        parent="abstractService"
        class="com.spring.ShippingService">
        <property name="shippedBy" value="xyz"/>
    </bean>
The shippingService bean inherits the value xyz 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.xyz.spring.OrderService"/>
    <beans>
However, instead of pre-assembling them in the XML configurations using imports, it is more flexible to configure them through theApplicationContext. 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, orall, 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.spring.OrderService"
        dependency-check="objects">
        <property name="companyName"
            value="xyz"/>
        <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 thedescription element. For example:
    <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.spring.OrderService">
        <constructor-arg ref="orderDAO"/>
    </bean>
 
    <bean id="billingService"
        class="com.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

 

13) Always externalize properties: Always externalize properties so that can be modified easily

Optimizing Spring Framework for App Engine Applications

Central to the Spring Framework is its Inversion of Control (IoC) container, alternatively known as Dependency Injection. It allows developers to compose disparate components into a fully working application ready for use. When an application is first loaded, Spring parses the configuration metadata and combine the application classes to create an application context. Depending on the complexity of the application, the initial time required to instantiate the framework can take a long time. This does not pose any problem for services that run in a load once and run forever environment but may become a problem for App Engine applications. App Engine frontend instances are dynamically scaled. That means App Engine automatically creates new instances when load increases and turns off instances when they are not being used. Reloading instances may result in additional latency for users. Frontend instances also have a 60 seconds deadline to complete a given request. Applications that take a long time to load will result in DeadlineExceededException. This article discusses ways you can optimize the initial load time for an application that uses the Spring framework.

Best Practices for App Engine Applications

The following are best practices that can optimize the loading time for App Engine applications that use the Spring Framework.

Reducing or Avoiding the Use of Component Scanning

Spring defines a set of stereotype annotations, which are markers for any class that fulfills a role within an application. For example, the @Repository annotation, which was introduced in Spring 2.0, is used for classes that fulfill the role of Data Access Object of a repository. Another example is the @Controller annotation, which indicates that a particular class serves the role of a controller in the Spring Web MVC framework. Spring provides an option to automatically detect stereotyped classes and register corresponding BeanDefinitions with the ApplicationContext, eliminating the need to specify the stereotyped classes in the XML configuration metadata file. This is achieved by implicitly detecting the candidate components by scanning the classpath and matching against filters.
Real-time component scanning is enabled by using the context:component-scan configuration element in the Spring XML configuration file.
When component scanning is enabled, during the application initialization phase Spring will have to read a large amount of data from the file system in real-time to scan for the stereotyped classes on the classpath. This can cause the initial request to an App Engine application to take an indeterministic amount of time to complete, despite the fact that the App Engine’s virtual file system is a very high performance system.
Disable component scanning by not using the following configuration element in the Spring XML configuration file:
<!-- Component scanning will significantly slow down application initialization time -->

<context:component-scan base-package=””/>
Instead, explicitly declare your dependencies, such as:
<bean id=”myComponentBean” class=”org.foo.MyComponent”/>

<bean id=”myOtherComponentBean” class=”org.bar.MyComponent”/>
·         If you must use component scanning, pay extra attention to the base-package. If the base-package references classes in a large JAR file, or if it references a significant number of JAR files, or if the base-package refers to a large amount of .class files, the application’s performance will be impacted negatively.
·         Here are some tips to help mitigate the impact of component scanning on your application’s performance:
·         Breaking up larger JAR files can improve performance of classpath scanning. This is because the application does not have as many classes to scan if Spring can determine which JARS are relevant.
·         It is not advisable to attempt to perform classpath scanning with UberJars or any other form of JAR files generated from “JAR composing” build tools.
·         The use of filters on annotations (e.g. the context:exclude-filter tag) will not help performance in App Engine. There are facilities in place that make this an insignificant performance gain for the application.
·         Try to avoid uploading a large amount of .class files; attempt to “JAR up” these .class files into smaller JAR files that will be compressed and therefore faster to load.
·         Reducing or Avoiding the Use of Relationship Autowiring
·         The Spring container can automatically wire relationships between collaboration beans using introspection of the bean classes. This eliminates the need to explicitly specify the relationships as properties or constructor arguments within the application configuration metadata.
·         Let’s see how the “automatic wiring” of the relationships is enabled. For example, consider the following Spring MVC Controller class with a DAO member,
·         @Controller
@RequestMapping("/movie")
public class MovieController {
  MovieDaoInterface movieDao;
  public void setMovieDao(MovieDaoInterface movieDao) {
    this.movieDao = movieDao;
  }
}
·         The Spring IoC uses the following XML configuration to set the member property for MovieController.
·         <bean class="com.example.controller.MovieController">
  <property name="movieDao" ref="movieDao"></property>
</bean>
<!-- movieDao is defined elsewhere in the container configuration -->
<bean id="movieDao" class="com.example.dao.MovieDao" />
·         Instead, you enable autowire by using the context:annotation-config element in the spring configuration file and define the bean as shown next:
·         <context:annotation-config />  <!-- Turn on Autowired -->
<bean class="com.example.controller.MovieController" autowire="byType">
</bean>
·         While automatic wiring can significantly reduce the complexity of specifying properties or constructor arguments through the use of the XML-based configuration, it significantly increases the time required to resolve the beans during application initialization time. The time penalty is worse when the wiring mode is byType. This is because, in this mode, Spring has to iterate over every bean defined in the application context and must perform Java introspection to find out its type.
·         If you need to use autowire, make sure that the container is reasonably sized and it uses the byName mode.
·         Disabling XML Validation in Production
·         To further reduce the loading time of an application, you can disable XML validation in production by following the steps below:
·         Create a class that extends XmlWebApplicationContext.
·         Override the initBeanDefinitionReader method.
·         Set the XmlBeanDefinitionReader validation mode to VALIDATION_NONE. XML validation is enabled if an App Engine application runs within the App Engine SDK and disabled when it runs in production mode.
·         import com.google.appengine.api.utils.SystemProperty;

public class Custom XmlWebApplicationContext extends XmlWebApplicationContext {
         protected void init BeanDefinitionReader(XmlBeanDefinitionReader beanDefinitionReader) {
                   super.init BeanDefinitionReader(beanDefinitionReader);
                   if (SystemProperty.environment.value() == SystemProperty.Environment.Value.Production) {
                     beanDefinitionReader.setValidating(false);
                     beanDefinitionReader.setNamespaceAware(true);
                   }
               }
}
·         Open the web.xml file.
·         Create a section.
·         Add a element whose value is contextClass.
·         Add a element whose value points to the class that you created before.
·         <context-param>
  <param-name>contextClass</param-name>
  <param-value>com.example.CustomXmlWebApplicationContext</param-value>
</context-param>
·         Using Lazy-Initialized Beans
·         Spring’s ApplicationContext creates and configures all singleton beans as part of the initialization process. This is desirable because if there are configuration errors they are discovered immediately. But this has a negative side effect of increasing the application loading time.
·         This may not be an issue for long-lived services which only have to start once, but is not desirable for the dynamic environment of App Engine applications.
·         For beans that are used less frequently, and are not required when the container initializes for the first request, this problem can be mitigated by setting the lazy-init attribute to true.
·         Lazy initialization is implemented using Aspect Oriented Programming (AOP), which may introduce a certain amount of control flow that may or may not be necessary. It uses proxies that construct and delegate to the dependent bean after the bean is requested. This can become a performance problem in situations where it would be just as quick to instantiate the dependency bean versus instantiating a delegating proxy. Lazy initialization can also introduce performance problems if it’s used extensively, and can also complicate the process of debugging.
·         In the Spring Framework the beans are singleton by default. Singletons are scoped within the IoC container. The use of the term singleton in Spring therefore refers to a single instance of the bean within the IoC container and has no strong relation to the lifecycle of the object in the virtual machine. Therefore, multiple instances of a Spring singleton can exist for any given classloader.
·         Significant application performance can be achieved by carefully choosing which beans must be initialized during the application loading time.
·         Avoiding Constructor Injection by Name
·         Spring 3.0 added support for using the constructor parameter name for value disambiguation. Let’s consider the following sample class as an example:
·         public class Movie {
  private String name;
  private String synopsis;

  public Movie(String name, String synopsis) {
    this.name = name;
    this.synopsis = synopsis;
  }
}
·         The corresponding configuration using injection by name is shown as below:
·         <bean id="movie" class="example.Movie">
  <constructor-arg name="name" value="ET" />
  <constructor-arg name="synopsis" value="Help ET go home" />
</bean>
·         To make this work “out of the box”, Spring requires that the code must be compiled with the debug flag enabled (-g for all debugging info, or -g:vars to be precise, for the local variable debug information). This allows Spring to look up the parameter name in the debug information. However, since this information is not cached in the JVM, it must be loaded from disk which causes significant I/O time penalty.
·         To solve this problem you can use one of the following guidelines:
·         Use the @ConstructorProperties annotation to explicitly name your constructor arguments as shown next.
·         public class Movie {
  // Fields omitted
  @ConstructorProperties(({“name”, “synopsis”})
  public Movie(String name, String synopsis) {
    this.name = name;
    this.synopsis = synopsis;
  }
}
·         Define the bean without using constructor injection by name:
·         <bean id="movie" class="example.Movie">
·           <constructor-arg index=0 value="ET" />
·           <constructor-arg index=1 value="Help ET go home" />
·         </bean>
·         However, constructor injection by name is a bad programming practice. It is an anti-pattern of dependency injection which relies on the consistent naming of constructor arguments. Here are the potential problems that may lead to problems that are difficult to debug.
·         When utilizing software that you do not control, the effective definition of the interface itself is extended to include information that is not part of the standard method signature in Java. Therefore, it is entirely possible that someone could change the name of a constructor argument without revising the major or minor versions of the built artifact, causing your application to fail.
·         Constructor injection can become problematic with any framework or system that rewrites the class bytecode using something similar to ASM. In Java, it is entirely possible to obtain the bytecode of a specific class and modify it to be reloaded by a classloader. Doing so can break linkage of the subsequently defined class with the source it was originally defined with. This means the lookup of the names of the constructor arguments will fail and this again may break the application unpredictably.



Comments

Popular posts from this blog

Conversion from Clob To String in java and Vice versa

/***reading Clob data from oracle table and setting to Pojo**/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import oracle.sql.CLOB;

import com.poc.one.pojo.StagedMessage;

public class MessageDao {
private static String url = "jdbc:oracle:thin:@172.22.22.198:1521:ORACLE";
private static String username = "ABC123";
private static String password = "ABC123";


public  List readClobToBO() throws Exception {

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement stmt = conn
.prepareStatement("SELECT ID, STORE_ID, MESSAGE_DATA FROM STAGED_MESSAGE ");
ResultSet resultSet = stmt.executeQuery();
List msgList= new ArrayList();

while (resultSet.next()) {

StagedMessage message = new StagedMessage();

message.setId(resultSet.getInt(1));
message.setStoreId(r…

Portable Java 8/ JDK8 setup without admin rights

Some time we got machine to work where we don't have access rights to install anything or if you do not want to install. You can get latest jdk running by this trick. Just follow step step & do comment if you like it.

Step by Step details to get running java from .exe setup without any admin rights. Get portable 7 zip from portableapps.comdownload java 8 from oracle  http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htmlopen 7 zip & extract jdk-8u102-windows-x64.exeyou will see below folders                .data                .pdata                .rdata                .reloc                .rsrc                .text                CERTIFICATE

          5.Go inside E:\jdk-8u102-windows-x64\.rsrc\1033\JAVA_CAB10you will find 111 file.

         6.extract it it some folder where you can find tools.zip again extract that to some folder say Java & copy it to very first folder of setup along with .data,.rsrc etc.
         7.Go to folder where you have co…

Multi Threading , Producer consumer problem in Java

Multi threading is topic which is always fascinating for java developer. I feel its more about practical the theory. So here i wanted to present sample examples which clear understanding for several multi threading concept.

In Theory basically thread which is light weight process.Thread shares mostly same memory space.
I said mostly because there is some space called thread local which is not common to threads & separate for each thread. We create thread whenever we wanted to use multicore of processor although that doesn't mean single core cant use it. In single core context switching works among different running thread.

for example suppose there is website which is showing latest price as well as offer as well as doing order booking all these things can be assigned to different thread to provide parallel processing.



There are 2 ways for creating a thread.

Extend a thread & Implement a Runnable class. Extending a class is little avoided since it closed possibility for e…