Подтвердить что ты не робот

Может ли @Inject быть добавлено в JSR 330 (например, @Autowire (required = false)?

Spring @Autowire может быть сконфигурирован таким образом, что Spring не будет вызывать ошибку, если не найдено подходящих кандидатов на автоуверсию: @Autowire(required=false)

Есть ли эквивалентная аннотация JSR-330? @Inject всегда терпит неудачу, если нет подходящего кандидата. Есть ли способ, которым я могу использовать @Inject, но не иметь фреймворка, если не найдены соответствующие типы? В такой степени я не смог найти документацию.

4b9b3361

Ответ 1

Нет... нет эквивалента для необязательного в JSR 330... если вы хотите использовать опциональную инъекцию, вам придется придерживаться аннотации @Autowired

Ответ 2

Я очень удивлен, что никто не упомянул java.util.Optional. Если вы используете Java 8, а версия Spring - 4.1 или выше (см. здесь), вместо

@Autowired(required = false)
private SomeBean someBean;

Вы можете просто использовать класс java.util.Optional, который поставляется с Java 8. Используйте его как:

@Inject
private Optional<SomeBean> someBean;

Этот экземпляр никогда не будет null, и вы можете использовать его как:

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

Таким образом, вы также можете выполнить инсталляцию конструктора, с некоторыми требуемыми beans и некоторыми beans, дает большую гибкость.

Примечание. К сожалению, Spring не поддерживает Guava com.google.common.base.Optional (см. здесь), поэтому этот метод будет работать, только если вы используют Java 8 (или выше).

Ответ 3

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 и true будет возвращено.

Возможно, вы сможете изменить это, подклассифицируя этот BeanPostProcessor и переопределяя метод determineRequiredStatus(Annotation), чтобы вернуть true, или, вернее, что-то "умнее".

Ответ 4

Можно создать дополнительную точку инъекции!

Вам нужно использовать поиск инъекций, как описано в 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() ленив, если вам нужно. Инъекция по умолчанию оценивается во время запуска и генерирует исключение, если не найдено beans, которое может быть введено, bean будет введено во время выполнения, но приложение не запустится, если это невозможно. В документации вы найдете больше примеров, включая фильтрацию инъецируемых экземпляров и многое другое.

Ответ 5

Инъекционная инъекция часто пропускается. Это добавляет большую гибкость. Проверьте доступность зависимости до ее получения. Неудовлетворенный get будет генерировать исключение, которое дорого. Использование:

@Inject
Instance<SomeType> instance;
SomeType instantiation;

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

Вы можете ограничить кандидатов на инъекции как обычно:

@Inject
@SomeAnnotation
Instance<SomeType> instance;