springjsr330

JSR-330 @Scope and Spring Don't Match


The java doc for the JSR-330 Scope annotation states "uses the instance for one injection, and then forgets it" implying that the instance is of scope prototype and the Singleton annotation is intended to create the singleton that is the default behavior with spring. So the question is, Why, when I use the Named annotation rather than the Spring Component annotation does Spring not follow the JSR guidelines and scope the bean as prototype? It seems to me like it should.

I would like to keep the spring dependencies consolidated to a single module and use JSR-330 everywhere else so If needed I can easily switch later.


Solution

  • So this is how I made what I want work:

    /**
     * JSR-330 assumes the default scope is prototype, however Spring IOC defaults to singleton scope.
     * This annotation is used to force the JSR-330 standard on the spring application.
     * 
     * This is done by registering this annotation with the spring bean factory post processor.
     * <pre>
     * <code>
     * public class PrototypeBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
     *   
     *   public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {
     *      for (String beanName : factory.getBeanDefinitionNames()) {
     *          if (factory.findAnnotationOnBean(beanName, Prototype.class) != null) {
     *              BeanDefinition beanDef = factory.getBeanDefinition(beanName);
     *              beanDef.setScope("prototype");
     *          }
     *      }
     *   }
     * }
     * </code>
     * </pre>
     *
     * @see javax.inject.Scope @Scope
     */
    @Scope
    @Documented
    @Retention(RUNTIME)
    public @interface Prototype {}
    

    I put this annotation in my core jar and then let the spring-boot app module do the work of processing the annotation.

    It works well for me but I am happy to hear any other suggestions.