Spring的@Autowire
可以配置为如果找不到匹配的autowire候选者,Spring不会抛出错误:@Autowire(required=false)
是否有等效的JSR-330注释?如果没有匹配的候选者,@Inject
总是会失败。有没有办法可以使用@Inject
但是如果没有找到匹配的类型,框架就会失败?我无法在那种程度上找到任何文件。
答案 0 :(得分:28)
您可以使用java.util.Optional
。
如果您使用 Java 8 且 Spring 版本为4.1
或更高版本(请参阅here),而不是
@Autowired(required = false)
private SomeBean someBean;
您可以使用 Java 8 附带的java.util.Optional
类。使用它像:
@Inject
private Optional<SomeBean> someBean;
此实例永远不会是null
,您可以像以下一样使用它:
if (someBean.isPresent()) {
// do your thing
}
这样你也可以进行构造函数注入,需要一些bean,一些bean可选,提供很大的灵活性。
注意:不幸的是,Spring不支持 Guava 的com.google.common.base.Optional
(请参阅here),因此只有在使用Java 8(或更高版本)时此方法才有效
答案 1 :(得分:13)
否...... JSR 330中没有可选的可选项...如果你想使用可选注入,那么你将不得不坚持使用特定于框架的@Autowired
注释
答案 2 :(得分:7)
实例注入经常被忽视。它增加了很大的灵活性在获取依赖项之前检查依赖项的可用性。不满意的获得将抛出一个昂贵的例外。使用:
@Inject
Instance<SomeType> instance;
SomeType instantiation;
if (!instance.isUnsatisfied()) {
instantiation = instance.get();
}
您可以正常限制注射候选者:
@Inject
@SomeAnnotation
Instance<SomeType> instance;
答案 3 :(得分:5)
AutowiredAnnotationBeanFactoryPostProcessor
(Spring 3.2)包含此方法以确定是否需要支持的“Autowire”注释:
/**
* 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;
}
}
简而言之,不,不是默认。
默认情况下要查找的方法名称为“必填”,而不是@Inject
注释中的字段,因此method
将为null
和{{1将被退回。
您可以通过继承此true
并覆盖BeanPostProcessor
方法来返回true,或者更确切地说,更聪明一些来更改它。
答案 4 :(得分:5)
可以创建一个可选的注射点!
您需要使用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){
}
甚至是所有类型的实例
@Inject
Instance<List<Type>> instances
如果需要,还可以延迟评估get()方法。默认注入在启动时评估,如果没有找到可以注入的bean则抛出异常,当然会在运行时注入bean,但如果不可能,应用程序将无法启动。 在文档中,您将找到更多示例,包括如何过滤注入的实例等等。