Spring-как внедрить конкретную реализацию интерфейса?
мне нужно ввести @Autowired конкретную реализацию класса обслуживания.
интерфейс:
public interface PostService {
...
}
реализация:
@Service("postServiceImpl")
public class PostServiceImpl implements PostService {
...
}
методы в службе с аннотацией @ Transactional
и теперь я хочу ввести postServiceImpl в мой контроллер-потому что мне нужно использовать один метод из реализации, которого нет в интерфейсе:
@Autowired
@Qualifier("postServiceImpl")
private PostServiceImpl postService;
Я NoSuchBeanDefinitionException со следующим сообщением:
нет квалификационного компонента типа [ (...) .PostServiceImpl] найдено для зависимость: ожидается не менее 1 Бина, который квалифицируется как autowire кандидат для этой зависимости.
когда я изменяю поле в моем контроллере на:
private PostService postService
это работает, но я не могу использовать конкретный метод из PostServiceImpl.
1 ответов
поскольку ваши методы аннотированы @Transactional
, spring создаст прокси во время выполнения, чтобы ввести код управления транзакциями. По умолчанию Spring использует динамический Прокси JDK для механизма проксирования, который прокси на основе интерфейсов.
Итак, в этом случае spring создает другой класс, который реализует PostService
интерфейс и создает bean этого класса. Определенно, это не может быть autowired PostServiceImpl
, так как это братья и сестры. Однако, если вы действительно хотите autowire на класс, вы можете заставить spring использовать CGLib прокси вместо этого, какие прокси используют подклассы. Это можно сделать, установив proxyTargetClass=true
в своем @EnableTransactionManagement
аннотация, если вы используете конфигурацию на основе Java.