java - ejemplo - @autowired que es
¿Puede @Inject hacerse opcional en JSR 330(como @Autowire(requerido=falso)? (5)
El @Autowire
de Spring se puede configurar de manera que Spring no arrojará un error si no se encuentran candidatos autowire coincidentes: @Autowire(required=false)
¿Hay una anotación equivalente a JSR-330? @Inject
siempre falla si no hay un candidato coincidente. ¿Hay alguna manera en que pueda usar @Inject
pero no tener el marco fallar si no se encuentran tipos coincidentes? No he podido encontrar ninguna documentación hasta ese punto.
¡Es posible crear un punto de inyección opcional!
Debe utilizar la búsqueda de inyección como se documenta en http://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#lookup
@Inject
Instance<Type> instance;
// In the code
try {
instance.get();
}catch (Exception e){
}
O incluso todas las instancias de un tipo
@Inject
Instance<List<Type>> instances
También el método get () se evalúa perezosamente si lo necesita. La Inyección predeterminada se evalúa en el momento de Inicio y lanza una excepción si no se encuentran frijoles que podrían inyectarse, el frijol se inyectará en tiempo de ejecución, por supuesto, pero la aplicación no se iniciará si esto es imposible. En la documentación encontrará más ejemplos, incluido cómo filtrar las instancias inyectadas y mucho, mucho más.
El AutowiredAnnotationBeanFactoryPostProcessor
(Spring 3.2) contiene este método para determinar si una anotación ''Autowire'' compatible es necesaria o no:
/**
* Determine if the annotated field or method requires its dependency.
* <p>A ''required'' dependency means that autowiring should fail when no beans
* are found. Otherwise, the autowiring process will simply bypass the field
* or method when no beans are found.
* @param annotation the Autowired annotation
* @return whether the annotation indicates that a dependency is required
*/
protected boolean determineRequiredStatus(Annotation annotation) {
try {
Method method = ReflectionUtils.findMethod(annotation.annotationType(), this.requiredParameterName);
if (method == null) {
// annotations like @Inject and @Value don''t have a method (attribute) named "required"
// -> default to required status
return true;
}
return (this.requiredParameterValue == (Boolean) ReflectionUtils.invokeMethod(method, annotation));
}
catch (Exception ex) {
// an exception was thrown during reflective invocation of the required attribute
// -> default to required status
return true;
}
}
En resumen, no, no por defecto.
El nombre del método que se busca de forma predeterminada es ''obligatorio'', que no es un campo en la anotación @Inject
, por lo tanto, el method
será null
y se devolverá true
.
Es posible que pueda cambiar eso subclasificando este BeanPostProcessor
y anulando el método determineRequiredStatus(Annotation)
para devolver verdadero, o más bien, algo "más inteligente".
La inyección de instancia a menudo se pasa por alto. Añade gran flexibilidad. Compruebe la disponibilidad de la dependencia antes de obtenerla. Un insatisfecho arrojará una excepción que es costosa. Utilizar:
@Inject
Instance<SomeType> instance;
SomeType instantiation;
if (!instance.isUnsatisfied()) {
instantiation = instance.get();
}
Puede restringir las inyecciones de forma normal:
@Inject
@SomeAnnotation
Instance<SomeType> instance;
No ... no hay un equivalente para opcional en JSR 330 ... si desea utilizar la inyección opcional, tendrá que atenerse a la anotación @Autowired
específica del marco
Puedes usar java.util.Optional
. Si está utilizando Java 8 y su versión Spring es 4.1
o superior (consulte here ), en lugar de
@Autowired(required = false)
private SomeBean someBean;
Puede usar la clase java.util.Optional
que viene con Java 8 . Utilízalo como:
@Inject
private Optional<SomeBean> someBean;
Esta instancia nunca será null
, y puedes usarla como:
if (someBean.isPresent()) {
// do your thing
}
De esta manera también puede hacer una inyección de constructor, con algunos granos requeridos y algunos granos opcionales, le da una gran flexibilidad.
Nota: Desafortunadamente, Spring no admite com.google.common.base.Optional
Guava (consulte here ), por lo que este método solo funcionará si está utilizando Java 8 (o superior).