2012-03-13 9 views
12

Me gustaría crear método de productor de frijol de un muelle que es consciente de que la invocó, por lo que he empezado con el siguiente código:¿Cuál es el equivalente de Spring DI del InjectionPoint de CDI?

@Configuration 
public class LoggerProvider { 

    @Bean 
    @Scope("prototype") 
    public Logger produceLogger() { 
     // get known WHAT bean/component invoked this producer 
     Class<?> clazz = ... 

     return LoggerFactory.getLogger(clazz); 
    } 
} 

¿Cómo puedo obtener la información que quiere obtener el grano ¿inyectado?

Estoy buscando un equivalente de CDI's InjectionPoint en el mundo de la primavera.

Respuesta

6

Hasta donde yo sé, Spring no tiene tal concepto.

Entonces, lo único que es consciente del punto que se procesa es un BeanPostProcessor.


Ejemplo:

@Target(PARAMETER) 
@Retention(RUNTIME) 
@Documented 
public @interface Logger {} 

public class LoggerInjectBeanPostProcessor implements BeanPostProcessor { 
    public Logger produceLogger() { 
     // get known WHAT bean/component invoked this producer 
     Class<?> clazz = ...  
     return LoggerFactory.getLogger(clazz); 
    } 


    @Override 
    public Object postProcessBeforeInitialization(final Object bean, 
      final String beanName) throws BeansException { 
     return bean; 
    } 

    @Override 
    public Object postProcessAfterInitialization(final Object bean, 
      final String beanName) throws BeansException { 

     ReflectionUtils.doWithFields(bean.getClass(), 
       new FieldCallback() { 
        @Override 
        public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { 
         field.set(bean, produceLogger()); 
        } 
       }, 
       new ReflectionUtils.FieldFilter() { 
        @Override 
        public boolean matches(final Field field) { 
          return field.getAnnotation(Logger.class) != null; 
        } 
       }); 

     return bean; 
    } 
} 
+0

Gracias Ralph! Ok, entonces este 'BeanPostProcessor' se invoca cada vez que se inyecta cualquier bean en cualquier lugar. ¿Hay alguna forma en que pueda reconocer ** qué ** será inyectado? Quiero decir que obtuve: 'postProcessBeforeInitialization (Object bean, String beanName)' donde 'bean' es un bean que quiere que se haga la inyección (la parte ** who ** que hice en mi pregunta), y' beanName 'es el nombre' bean'. Ahora no sé qué campo de 'bean' quiere que se haga la inyección; en otras palabras, no sé si el bean inyectado es' LoggerProvider' u otra cosa. –

+0

¡Según lo que entiendo, el post procesador se invoca después de que se crea un bean! (no inyectado en ninguna parte) La idea era implementar su propio marco de inyección pequeño sobre ese procesador de posos de frijol. – Ralph

+0

Ok, entonces se llamará al implementador 'BeanPostProcessor' siempre que se cree un bean. Entonces, tu idea era implementar 'postProcessBeforeInitialization' y por ej. Escanee los campos que tienen mi anotación personalizada (digamos '@ Logger') y, a través de la reflexión, inicialice dicho campo usando mi propia lógica personalizada. ¿Fue este tu enfoque o lo he complicado demasiado? ¡Gracias una vez más! –

15

primavera 4.3.0 permite InjectionPoint y DependencyDescriptor parámetros para los métodos de producción de frijol:

@Configuration 
public class LoggerProvider { 

    @Bean 
    @Scope("prototype") 
    public Logger produceLogger(InjectionPoint injectionPoint) { 
     Class<?> clazz = injectionPoint.getMember().getDeclaringClass(); 

     return LoggerFactory.getLogger(clazz); 
    } 
} 

Por cierto, the issue for this feature SPR-14033 enlaces a a comment on a blog post que une a esta pregunta .

+0

Si inserto esto en otro bean, que también tiene un alcance de prototipo, ¿no creará esto un registrador para cada instancia de ese bean, en lugar de compartir una sola instancia estática? –

+1

@ RupertMadden-Abbott El marco de registro normalmente almacena en caché los registradores. Por ejemplo, vea esta pregunta sobre el marco de trabajo SLF4J: [¿Cuál es la sobrecarga de crear un registrador SLF4J en contextos estáticos vs. no estáticos?] (Http://stackoverflow.com/questions/10345109/whats-the-overhead-of -creating-a-slf4j-loggers-in-static-vs-non-static-context) –

Cuestiones relacionadas