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.