Spring Framework Tutorial

Software Setup and Configuration (STS/Eclipse/IntelliJ)

Core Spring

Spring Annotations

Spring Data

Spring JDBC

Spring Security

Custom Bean Scope in Spring

In Spring, a bean's scope determines the lifecycle and visibility of that bean in the contexts it is deployed in. Out of the box, Spring provides several bean scopes like singleton, prototype, request, session, and application. However, there are scenarios when you might want to define your own custom bean scope.

Here's a step-by-step guide to creating a custom bean scope in Spring:

1. Implement the Scope Interface

You need to implement the org.springframework.beans.factory.config.Scope interface. This interface has several methods that you have to provide implementations for:

  • get: Return an instance (possibly shared or independent) of the object managed by this bean scope.
  • remove: Remove the object with the given name from the underlying scope.
  • registerDestructionCallback: Register a callback to be executed upon destruction of the specified object in the scope.
  • resolveContextualObject: Resolve the contextual object for the given key, if any.
  • getConversationId: Return the conversation ID for the current underlying scope, if any.

2. Register the Custom Scope

Once you have implemented the Scope interface, you need to register the custom scope with the Spring container using the ConfigurableBeanFactory.registerScope() method.

@Configuration
public class CustomScopeConfig {

    @Autowired
    private ConfigurableBeanFactory beanFactory;

    @PostConstruct
    public void registerMyScope() {
        beanFactory.registerScope("myCustomScope", new MyCustomScope());
    }
}

3. Use the Custom Scope

Now that your custom scope is registered, you can use it just like the built-in scopes.

@Bean
@Scope("myCustomScope")
public MyBean myBean() {
    return new MyBean();
}

Example: Thread Scope

As an illustrative example, let's create a custom bean scope that scopes beans to the lifecycle of a single thread:

public class ThreadScope implements Scope {

    private final ThreadLocal<Map<String, Object>> threadScope =
            ThreadLocal.withInitial(HashMap::new);

    @Override
    public Object get(String name, ObjectFactory<?> objectFactory) {
        Map<String, Object> scope = threadScope.get();
        if (!scope.containsKey(name)) {
            scope.put(name, objectFactory.getObject());
        }
        return scope.get(name);
    }

    @Override
    public Object remove(String name) {
        return threadScope.get().remove(name);
    }

    @Override
    public void registerDestructionCallback(String name, Runnable callback) {
        // Custom cleanup can be done here if needed
    }

    @Override
    public Object resolveContextualObject(String key) {
        return null;
    }

    @Override
    public String getConversationId() {
        return String.valueOf(Thread.currentThread().getId());
    }
}

With this custom scope, beans are scoped to individual threads. If you fetch a bean from the context in a specific thread, you'll always get the same instance within that thread. However, in a different thread, you'll get a different instance.

Creating custom bean scopes can be a powerful way to control the lifecycle and visibility of beans in your application, but it's also a more advanced feature that can add complexity. It's essential to ensure that the custom scope fits well with your application's requirements and architecture.

  1. Creating and Using Custom Scopes for Spring Beans:

    • Description: Create custom scopes by implementing the Scope interface and register them in the Spring application context.
    • Code:
      public class CustomScope implements Scope {
          // Implementation details
      }
      
  2. Defining Custom Scope in Spring ApplicationContext:

    • Description: Define a custom scope in the Spring application context XML configuration.
    • Code:
      <bean id="myBean" class="com.example.MyBean" scope="customScope"/>
      
  3. Implementing a Custom Bean Scope in Spring:

    • Description: Implement a custom scope by providing methods for bean creation, destruction, and retrieval.
    • Code:
      public class CustomScope implements Scope {
          // Implementation details for create, destroy, and get
      }
      
  4. How to Register and Configure Custom Scopes in Spring:

    • Description: Register and configure custom scopes by adding them to the Spring application context.
    • Code:
      @Configuration
      public class AppConfig {
          @Bean
          public static CustomScope customScope() {
              return new CustomScope();
          }
      }
      
  5. Configuring Thread-Scoped Beans in Spring Framework:

    • Description: Thread-scoped beans are those whose lifecycle is tied to a specific thread. Configure them to manage thread-local state.
    • Code:
      @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
      
  6. Request-Scoped Beans and Custom Scopes in Spring MVC:

    • Description: Request-scoped beans are tied to a specific HTTP request in a Spring MVC application. Custom scopes can be applied to customize this behavior.
    • Code:
      @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)