29

可以配置Spring @Autowire,如果没有找到匹配的自动装配候选者,Spring 不会抛出错误:@Autowire(required=false)

是否有等效的 JSR-330 注释? @Inject如果没有匹配的候选人,总是失败。如果没有找到匹配的类型,有什么方法可以使用@Inject但框架不会失败?我还没有找到任何文件到那个程度。

4

6 回答 6

37

您可以使用java.util.Optional. 如果您使用的是Java 8并且您的Spring版本是4.1或更高版本(请参阅此处),而不是

@Autowired(required = false)
private SomeBean someBean;

您可以只使用Java 8java.util.Optional附带的类。像这样使用它:

@Inject
private Optional<SomeBean> someBean;

这个实例永远不会是null,你可以像这样使用它:

if (someBean.isPresent()) {
   // do your thing
}

通过这种方式,您还可以进行构造函数注入,其中一些 bean 是必需的,一些 bean 是可选的,提供了很大的灵活性。

注意:不幸的是,Spring 不支持Guavacom.google.common.base.Optional(请参阅此处),因此此方法仅在您使用 Java 8(或更高版本)时才有效。

于 2016-03-15T16:04:58.833 回答
16

不...在 JSR 330 中没有可选的等效项...如果您想使用可选注入,那么您将不得不坚持使用特定于框架的@Autowired注释

于 2013-10-21T03:41:35.557 回答
13

实例注入经常被忽视。它增加了很大的灵活性。在获取依赖项之前检查它的可用性。不满意的 get 将抛出一个昂贵的异常。利用:

@Inject
Instance<SomeType> instance;
SomeType instantiation;

if (!instance.isUnsatisfied()) {
    instantiation = instance.get();
}

您可以正常限制注入候选者:

@Inject
@SomeAnnotation
Instance<SomeType> instance;
于 2015-02-24T21:25:31.303 回答
7

可以创建一个可选的注入点!

您需要使用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 将在运行时注入,但如果不可能,应用程序将不会启动。在文档中,您将找到更多示例,包括如何过滤注入的实例等等。

于 2014-08-15T14:01:50.173 回答
5

( AutowiredAnnotationBeanFactoryPostProcessorSpring 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;
        }
    }

简而言之,不,默认情况下不是。

默认情况下正在查找的方法名称是'required',它不是@Inject注释上的字段,因此将method被返回。nulltrue

您可以通过继承 thisBeanPostProcessor并覆盖该determineRequiredStatus(Annotation)方法以返回 true,或者更确切地说,一些“更智能”的东西来改变它。

于 2013-10-21T03:41:51.173 回答
0

弹簧@Nullable支持@Inject

@Inject
@Nullable
void setSomeBean(SomeBean someBean)
于 2022-01-18T13:56:39.740 回答