Почему пружина не может работать с простыми типами? - PullRequest
2 голосов
/ 15 марта 2012

На работе для конкретного случая мы используем:

context.getAutowireCapableBeanFactory().autowireBeanProperties(
   serializer, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false
);

Сегодня мне пришлось автоматически передать значение в мой bean-компонент сериализатора, которое предоставляется FactoryBean.

Моя первая попытка состояла в том, чтобы просто использовать простой идентификатор фабрики, но он не работал.

После этого я попробовал много решений, которые я прочитал здесь, используя @Resource, @Autowired, @Qualifier и т. Д.

Наконец, посмотрев, как работает внедрение бина, я обнаружил, что Spring никогда не вводит «простые свойства»

/**
 * Return an array of non-simple bean properties that are unsatisfied.
 * These are probably unsatisfied references to other beans in the
 * factory. Does not include simple properties like primitives or Strings.
 * @param mbd the merged bean definition the bean was created with
 * @param bw the BeanWrapper the bean was created with
 * @return an array of bean property names
 * @see org.springframework.beans.BeanUtils#isSimpleProperty
 */
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
    Set<String> result = new TreeSet<String>();
    PropertyValues pvs = mbd.getPropertyValues();
    PropertyDescriptor[] pds = bw.getPropertyDescriptors();
    for (PropertyDescriptor pd : pds) {
        if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
            result.add(pd.getName());
        }
    }
    return StringUtils.toStringArray(result);
}

Я также нашел в документации Spring:

Обратите также внимание, что в настоящее время невозможно автоматически связывать так называемые простые свойства, такие как примитивы, строки и классы (и массивы таких простых свойств).(Это отредактировано и должно рассматриваться как особенность.)

Наконец, я знаю, почему мой фабричный бин не может внедрять в мою собственность: бин для инъекции - это Enum, который является "простым"свойство "(согласно коду)

Мне просто интересно, почему, по замыслу, запрещено автоматически связывать простые свойства, особенно в случае простого свойства, введенного FactoryBean.

Кроме того, я вижу, как может возникнуть проблема с автопроводкой строки по типу, но в чем проблема с автоподключением по имени?

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

Вы должны быть в состоянии достичь того, что вам нужно с помощью SpringEL:

class MyClass {
  @Value("#{factoryBeanName}")
  private int myValue;
  ...
}

на самом деле я не на 100% уверен, что это будет работать точно так же, как описано выше, но вы поймете, вы можете попробовать #{myBean.someMethod()}вместо этого.

0 голосов
/ 15 марта 2012

Хорошо, рассмотрим случай, когда в контексте есть несколько «бинов» одного (примитивного) типа.Как мог Spring выяснить, какой именно вводить?

Это в основном та же самая ситуация, что у Spring с автопроводкой чего-либо, но гораздо более вероятно, что в контексте Spring есть несколько экземпляров String или Integer, тогдаявляются экземплярами com.yourcorp.SomeClass.Фактически, если вы перечислите bean-компоненты в своем весеннем контексте, вы увидите, что в нем почти всегда есть несколько экземпляров String.

Я предполагаю, что разработчики Spring просто решили, что больше проблем, чем пользыв функции, так как она почти всегда не будет работать в любом случае.

...