Java @Inject 可以在 JSR 330 中成为可选的吗(比如 @Autowire(required=false))?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19485878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can @Inject be made optional in JSR 330 (like @Autowire(required=false)?
提问by Eric B.
Spring's @Autowire
can be configured such that Spring will not throw an error if no matching autowire candidates are found: @Autowire(required=false)
Spring@Autowire
可以配置为如果没有找到匹配的自动装配候选者,Spring 不会抛出错误:@Autowire(required=false)
Is there an equivalent JSR-330 annotation? @Inject
always fails if there is no matching candidate. Is there any way I can use @Inject
but not have the framework fail if no matching types are found? I haven't been able to find any documentation to that extent.
是否有等效的 JSR-330 注释? @Inject
如果没有匹配的候选人,总是失败。@Inject
如果找不到匹配的类型,有什么方法可以使用但不会使框架失败?我一直无法找到任何文档到那个程度。
采纳答案by Arun P Johny
No... there is no equivalent for optional in JSR 330... if you want to use optional injection then you will have to stick with the framework specific @Autowired
annotation
不……在 JSR 330 中没有与 optional 等效的东西……如果您想使用可选注入,那么您将不得不坚持使用特定于框架的@Autowired
注释
回答by nicholas.hauschild
The AutowiredAnnotationBeanFactoryPostProcessor
(Spring 3.2) contains this method to determine if a supported 'Autowire' annotation is required or not:
的AutowiredAnnotationBeanFactoryPostProcessor
(弹簧3.2)包含此方法,以确定是否需要或不支持的“自动装配”注释:
/**
* 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;
}
}
In short, no, not by default.
简而言之,不,默认情况下不是。
The method name that is being looked for by default is 'required', which is not a field on the @Inject
annotation, thus, method
will be null
and true
will be returned.
正在由默认寻找方法名是“需要”,这是不上一个字段@Inject
注释,从而,method
将null
与true
将被返回。
You may be able to change that by subclassing this BeanPostProcessor
and overriding the determineRequiredStatus(Annotation)
method to return true, or rather, something 'smarter'.
您可以通过子类化 thisBeanPostProcessor
并覆盖该determineRequiredStatus(Annotation)
方法以返回 true,或者更确切地说,“更智能”的东西来改变它。
回答by Giovanni Silva
It's is possible to create a optional injection point!
可以创建一个可选的注入点!
You need to use injection lookup as documented in http://docs.jboss.org/weld/reference/latest/en-US/html/injection.html#lookup
您需要使用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){
}
Or even all instances of a type
甚至一个类型的所有实例
@Inject
Instance<List<Type>> instances
Also the get() method is lazy evaluated if you need. The default Injection evaluates at Startup time and throw an exception if no beans are found that could be injected, the bean will be injected at runtime of course, but the application will not start if this is impossible. In the documentation you will find more examples, including how to filter the instances injected and much, much more.
如果需要,get() 方法也会被惰性评估。默认的注入在启动时进行评估,如果没有发现可以注入的 bean,则抛出异常,当然,bean 将在运行时注入,但如果这是不可能的,应用程序将不会启动。在文档中,您将找到更多示例,包括如何过滤注入的实例等等。
回答by Steve Brewin
Instance injection is often overlooked. It adds great flexibility. Check the availability of the dependency prior to getting it. An unsatisfied get will throw an exception which is expensive. Use:
实例注入经常被忽视。它增加了极大的灵活性。在获取依赖项之前检查它的可用性。一个不满意的 get 会抛出一个代价高昂的异常。用:
@Inject
Instance<SomeType> instance;
SomeType instantiation;
if (!instance.isUnsatisfied()) {
instantiation = instance.get();
}
You can restrict the injection candidates as normal:
您可以像往常一样限制注射候选者:
@Inject
@SomeAnnotation
Instance<SomeType> instance;
回答by Utku ?zdemir
You can use java.util.Optional
.
If you are using Java 8and your Springversion is 4.1
or above (see here), instead of
您可以使用java.util.Optional
. 如果您使用的是Java 8并且您的Spring版本是4.1
或更高版本(请参阅此处),而不是
@Autowired(required = false)
private SomeBean someBean;
You can just use java.util.Optional
class that came with Java 8. Use it like:
您可以只使用Java 8java.util.Optional
附带的类。像这样使用它:
@Inject
private Optional<SomeBean> someBean;
This instance will never be null
, and you can use it like:
这个实例永远不会是null
,你可以像这样使用它:
if (someBean.isPresent()) {
// do your thing
}
This way you can also do constructor injection, with some beans required and some beans optional, gives great flexibility.
通过这种方式,您还可以进行构造函数注入,其中一些 bean 是必需的,而一些 bean 是可选的,这提供了很大的灵活性。
Note: Unfortunately Spring does not support Guava's com.google.common.base.Optional
(see here), so this method will work only if you are using Java 8 (or above).
注意:不幸的是 Spring 不支持Guava的com.google.common.base.Optional
(请参阅此处),因此此方法仅在您使用 Java 8(或更高版本)时才有效。