Bean Scope

IoC container creates and manages the life cycle of Beans. Every time, we request ApplicationContext for a Bean, do we get a new bean or a copy of the existing bean?

We get the same bean. Because, the default scope is Singleton. So the ApplicationContext returns the same bean each time we request it for a bean.

  • Singleton scope – One instance of Bean per Spring Context.
  • Prototype scope – New Bean whenever requested.
  • request scope – One bean per HTTP request
  • session scope – one bean per specific user HTTP session

By Default, any Spring bean is a Singleton.

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)

To specify a different scope, use the following :

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class BinarySearchImpl { 
    @Autowired
    SortingAlgorithm sortAlgorithm; // uses BubbleSortAlgorithm
    ....
}

Using proxyMode :

If a Bean of scope “singleton” is using a dependency and the dependency bean is of scope “prototype” then :

If we want the dependency bean to return a new Bean each time the main bean is requested for, we have to use “proxyMode” on the dependency bean.

@Component
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class PersonDAO { 
     @Autowired 
     JdbcConnection jdbcConnection;
     
     public JdbcConnection getJdbcConnection() { 
          return jdbcConnection; 
     }

     public void setJdbcConnection(JdbcConnection jdbcConnection) { 
          this.jdbcConnection = jdbcConnection; 
     }
}

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, 
          proxyMode = ScopedProxyMode.TARGET_CLASS)
public class JdbcConnection { 
    public JdbcConnection() { 
        System.out.println("JDBC Connection"); 
    }
}

@SpringBootApplication
public class SpringbootScopeProjectApplication { 
      public static final Logger LOGGER = 
               LoggerFactory.getLogger(SpringbootScopeProjectApplication.class); 
     
      public static void main(String[] args) { 
           ApplicationContext applicationContext = 
                SpringApplication.run(SpringbootScopeProjectApplication.class, args); 
           PersonDAO personDao = applicationContext.getBean(PersonDAO.class); 
           PersonDAO personDao2 = applicationContext.getBean(PersonDAO.class); 

           LOGGER.info("{}", personDao); // PersonDAO@1115ec15
           LOGGER.info("{}", personDao.getJdbcConnection()); // JdbcConnection@4241e0f4
           LOGGER.info("{}", personDao.getJdbcConnection()); // JdbcConnection@6c2ed0cd

           LOGGER.info("{}", personDao2); // PersonDAO@1115ec15
           LOGGER.info("{}", personDao2.getJdbcConnection()); // JdbcConnection@4ebff610
     }
}

You can see in the above example that, PersonDAO which is of Singleton scope is returning the same bean, however the dependency bean, JdbcConnection bean is returning a new instance each time.

Spring Framework Singleton scope Vs Singleton pattern ?

Singleton Pattern – one instance per JVM

Singleton scope – one bean instance per ApplicationContext. In case, if there are 5 ApplicationContext present in a JVM, we will have 5 Singleton scope Spring Beans.