1

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.

peekay
  • 1,259
  • 2
  • 25
  • 49
  • Because the default in Spring is singleton (as documented) it also doesn't say that they are a fully compliant JSR-330 container they only support the annotations. – M. Deinum Jul 07 '17 at 05:46
  • What are you trying to do - test Spring compatibility with JSR-330? What's the use of this in your code? – Abhijit Sarkar Jul 07 '17 at 20:40
  • The application is a multi module gradle project. The point of this is to seclude the DI framework to a single module and have the rest of the modules use JSR-330. This will allow me to change DI framworks later with out needing to make changes in every module. So my answer below will force the spring portion of the application to follow the JSR specification on scoping of the beans as well as provide a clear representation of the scope of each bean. – peekay Jul 09 '17 at 15:25

1 Answers1

0

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.

peekay
  • 1,259
  • 2
  • 25
  • 49