#java #spring
#java #весна
Вопрос:
Можем ли мы внедрить служебный компонент без конструктора по умолчанию в контроллер?
У меня есть следующий контроллер
@Controller
public class ArticleController {
@Autowired
private WithConstructorService withConstructorService;
...
}
И мой сервис:
@Service
public class WithConstructorServiceImpl implements WithConstructorService {
String name;
String address;
public WithConstructorServiceImpl(String name, String address) {
super();
this.name = name;
this.address = address;
}
}
Я получаю исключение
SEVERE: Servlet /springheat threw load() exception
java.lang.NoSuchMethodException: WithConstructorServiceImpl.<init>()
Обновить:
Я делаю предположение здесь, но можем ли мы сделать какую-то магию AOP и по-прежнему использовать метод аннотированного конструктора arg service?
Комментарии:
1. технически, это не java «bean», если у него нет конструктора по умолчанию.
2. Я упоминал об этом с точки зрения spring bean.
Ответ №1:
Если вы используете spring 3, вы можете использовать @Value
аннотацию для подключения полей name и address, и тогда их не нужно устанавливать через конструктор. Или не используйте @Service
аннотацию и вместо этого объявите свой компонент в xml с соответствующими <constructor-arg>
тегами.
В любом случае, контейнер spring должен знать, где получить значения для name и address, иначе он не сможет создать ваш WithConstructorServiceImpl .
Комментарии:
1. Я делаю предположение здесь, но можем ли мы использовать некоторую магию AOP и по-прежнему использовать метод службы аннотированного конструктора arg ?… обновил вопрос тем же запросом.
Ответ №2:
Вы можете это сделать, но поскольку Spring должен создать экземпляр компонента, вы должны сообщить ему, какие значения передавать конструктору.
Первая возможность: автоматическое подключение двух аргументов:
@Autowired
public WithConstructorServiceImpl(@Qualifier("theNameBean") String name,
@Qualifier("theAdressBean") String address) {
В этом случае вам нужно будет объявить два компонента типа String в context.xml файл с соответствующим именем.
Вторая возможность: объявить сам компонент в context.xml файл и сообщите Spring, какие аргументы он должен передать конструктору.
Комментарии:
1. Не могли бы вы поделиться, как объявить «два компонента типа string в context.xml » для полноты картины?
Ответ №3:
Нет, вы не можете. Потому что, когда вводится компонент, он создает сам компонент, используя конструктор по умолчанию, и только после этого вводятся все его свойства.
Что вы можете сделать, так это просто создать сеттеры для name и address, а затем добавить их к введенному компоненту.