Самовсасывание с пружиной

Я попробовал следующий код с Spring 3.x, который не BeanNotFoundException с BeanNotFoundException и он должен соответствовать ответам на вопрос, который я задал раньше. Могу ли я ввести тот же class, используя Spring?

 @Service public class UserService implements Service{ @Autowired private Service self; } 

Поскольку я пытался использовать это с помощью Java 6, я обнаружил, что следующий код работает нормально:

 @Service(value = "someService") public class UserService implements Service{ @Resource(name = "someService") private Service self; } 

но я не понимаю, как он решает циклическую зависимость.

РЕДАКТИРОВАТЬ:
Вот сообщение об ошибке. ОП упомянул об этом в комментарии к одному из ответов:

Вызвано: org.springframework.beans.factory.NoSuchBeanDefinitionException: не найдено подходящего компонента типа [com.spring.service.Service] для зависимостей: ожидается как минимум 1 компонент, который квалифицируется как кандидат autwire для этой зависимости. Аннотации зависимостей: {@ org.springframework.beans.factory.annotation.Autowired (required = true)}

Обновление: февраль 2016 года

Автосалон автоматически будет поддерживаться в Spring Framework 4.3. Реализация можно увидеть в этом коммите GitHub .


Определенная причина, по которой вы не можете автоувериться, заключается в том, что реализация метода Spring DefaultListableBeanFactory.findAutowireCandidates(String, Class, DependencyDescriptor) явно исключает возможность. Это видно из следующей выдержки из этого метода:

 for (String candidateName : candidateNames) { if (!candidateName.equals(beanName) && isAutowireCandidate(candidateName, descriptor)) { result.put(candidateName, getBean(candidateName)); } } 

FYI: имя bean-компонента (то есть, beanNamebeanName . Этот компонент на самом деле является кандидатом на автоподключение, но указанное выше if-условие возвращает false (поскольку имя candidateName действительно равно beanName ). Таким образом, вы просто не можете autowire bean с собой (по крайней мере, не с Spring 3.1 M1).

Теперь о том, является ли это предполагаемое поведение семантически, это другой вопрос. 😉

Я спрошу Юргена и посмотрю, что он скажет.

С Уважением,

Сэм (главный источник энергии)

ps Я открыл проблему Spring JIRA, чтобы рассмотреть возможность поддержки самоавтоматизации по типу с помощью @Autowired. Не стесняйтесь смотреть или голосовать за эту проблему здесь: https://jira.springsource.org/browse/SPR-8450

Этот код также работает:

 @Service public class UserService implements Service { @Autowired private ApplicationContext applicationContext; private Service self; @PostConstruct private void init() { self = applicationContext.getBean(UserService.class); } } 

Я не знаю почему, но кажется, что Spring может получить компонент из ApplicationContext если он создан , но не инициализирован . @Autowired работы перед инициализацией и не могут найти один и тот же компонент. Итак, @Resource возможно, работает после @Autowired и перед @PostConstruct .

Но я не знаю, просто размышляю. Во всяком случае, хороший вопрос.

Кстати, более элегантным решением проблемы самозапуска является использование AspectJ Load-Time Weaving для ваших транзакционных прокси-серверов (или любого используемого вами AOP-прокси, который вы используете).

Например, при управлении транзакциями, основанном на аннотациях, вы можете использовать режим «aspectj» следующим образом:

  

Обратите внимание, что режим по умолчанию – «прокси» (т. Е. Динамические прокси-серверы JDK).

С Уважением,

Сэм

Учитывая вышеприведенный код, я не вижу циклической зависимости. Вы вводите некоторый экземпляр службы в UserService. Реализация внедренной службы необязательно должна быть другой UserService, поэтому циклическая зависимость не существует.

Я не понимаю, почему вы должны вводить UserService в UserService, но я надеюсь, что это теоретическая попытка или такая.

Получить прокси AOP из самого вопроса объекта предлагает альтернативный хакерский подход с AopContext.currentProxy() который может быть подходящим для особых случаев.

Похоже, что Spring создает и настраивает объект, а затем помещает его в контекст контекста bean. Но, в случае Java, я думаю, что он создает объект и связывает его с именем и во время настройки, когда объект просматривается именем, которое он находит в контексте.

Давайте будем гением компьютера.