Spring Tutorial - Spring Bean Scope








When defining Java bean in Spring xml configuration or using the Spring annotation we can mark a Java bean as singleton or prototype.

If a Java bean is marked as singleton, each time we call to get the bean we get the same instance.

If a Java bean is marked as prototype, each time we will get a new instance.

Java Bean

The following code defines a Java bean with a String type property.

package com.java2s.common;
public class MyService 
{
  String message;
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
}




Singleton

If no bean scope is specified in bean configuration file, default to singleton.

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
       <bean id="customerService" 
            class="com.java2s.common.MyService" />
</beans>

Here is the code to run the xml configuration defined above.

package com.java2s.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App 
{
    public static void main( String[] args )
    {
      ApplicationContext context = 
                 new ClassPathXmlApplicationContext(new String[] {"SpringBeans.xml"});
      MyService customerA = (MyService)context.getBean("customerService");
      customerA.setMessage("Message by customerA");
      System.out.println("Message : " + customerA.getMessage());
      //retrieve it again
      MyService custB = (MyService)context.getBean("customerService");
      System.out.println("Message : " + custB.getMessage());
    }
}

Output

Message : Message by customerA
Message : Message by customerA

The code above get MyService twice from the ApplicationContext. And it sets a String value for the message after the first call.

From the output we can see that both getMessage() call return the same message, which means the ApplicationContext uses one copy of the MyService.

If a bean is a singleton scope in Spring IoC container, getBean() will always return the same instance.



Download Java2s_Spring_Singleton_Scope.zip





Prototype

To get a new 'customerService' bean instance every time we call getBean(), use prototype scope.

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
   <bean id="customerService" class="com.java2s.common.MyService" 
         scope="prototype"/>
</beans>

Run it again

From the output we can see that the second call to the context.getBean("customerService"); we got a new instance of MyService.



Download Java2s_Spring_Prototype_Scope.zip

Bean scopes annotation

The following code shows how to use the annotation to mark the bean scope.

package com.java2s.common;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
@Service
@Scope("prototype")
public class MyService {
  String message;
  public String getMessage() {
    return message;
  }
  public void setMessage(String message) {
    this.message = message;
  }
}

The following code shows how to enable auto component scanning.

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-2.5.xsd">
       <context:component-scan base-package="com.java2s.common" />
</beans>

Here is the new App.java class to run the configuration above. The customerService is changed to myService. Spring automatically creates a bean name from the class name by lower case the first letter.

package com.java2s.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App 
{
    public static void main( String[] args )
    {
      ApplicationContext context = 
                 new ClassPathXmlApplicationContext(new String[] {"SpringBeans.xml"});
      MyService customerA = (MyService)context.getBean("myService");
      customerA.setMessage("Message by customerA");
      System.out.println("Message : " + customerA.getMessage());
      //retrieve it again
      MyService custB = (MyService)context.getBean("myService");
      System.out.println("Message : " + custB.getMessage());
    }
}

Run it again



Download Java2s_Spring_Beans_Scope_Annotation.zip