Я разрабатываю приложение с использованием Spring. Я должен использовать @Service
аннотацию. У меня есть ServiceI
и ServiceImpl
такой то ServiceImpl implements ServiceI
. Я не понимаю, где мне хранить @Service
аннотацию.
Должен ли я аннотировать интерфейс или реализацию @Service
? В чем разница между этими двумя подходами?
Ответы:
Я никогда не помещаю
@Component
(или@Service
...) в интерфейс, потому что это делает интерфейс бесполезным. Позвольте мне объяснить почему.Утверждение 1: Если у вас есть интерфейс, вы хотите использовать этот интерфейс для типа точки впрыска.
Утверждение 2: Назначение интерфейса состоит в том, что он определяет контракт, который может быть реализован несколькими реализациями. С другой стороны у вас есть точка инъекции (
@Autowired
). Имея только один интерфейс и только один класс, реализующий его, (IMHO) бесполезно и нарушает YAGNI .факт: Когда вы ставите:
@Component
(или@Service
, ...) в интерфейсе,тогда вы получите и
NoUniqueBeanDefinitionException
(или у вас есть особые настройки конфигурации со средой, профилями или квалификаторами ...)Вывод: если вы используете
@Component
(или@Service
, ...) в интерфейсе, вы должны нарушить хотя бы одно из двух правил. Поэтому я думаю, что это бесполезно (за исключением некоторых редких сценариев) устанавливать@Component
на уровне интерфейса.Интерфейсы Spring-Data-JPA Repository - это нечто совершенно иное
источник
@Transactional
это один из примеров использования прокси для bean-компонента. АОП - еще один.В основном аннотации, такие как @Service , @Repository , @Component и т.д., все служат одной цели:
Из моего опыта я всегда использовать
@Service
аннотацию на интерфейсы или абстрактные классы и аннотации , как@Component
и@Repository
для их реализации.@Component
аннотацию, которую я использую для тех классов, которые служат базовым целям, простые компоненты Spring, не более того.@Repository
аннотацию, которую я использую вDAO
слое, например, если мне нужно связаться с базой данных, выполнить некоторые транзакции и т. д.Поэтому я предлагаю аннотировать ваш интерфейс этим
@Service
и другими слоями в зависимости от функциональности.источник
Я
@Component
,@Service
,@Controller
и@Repository
аннотации только на классы реализации , а не на интерфейсе. Но@Autowired
аннотация с интерфейсами у меня все еще работала.источник
Плюсы размещения аннотации в @Service в том, что она дает намек на то, что это служба. Я не знаю, унаследует ли какой-либо реализующий класс по умолчанию эту аннотацию.
Минус в том, что вы связываете свой интерфейс с определенной структурой, например Spring, с помощью специальной аннотации Spring. Поскольку интерфейсы должны быть отделены от реализации, я бы не предлагал использовать какие-либо аннотации для конкретной платформы или объектную часть вашего интерфейса.
источник
Одним из преимуществ Spring является простота переключения реализации службы (или другой). Для этого вам нужно аннотировать интерфейс и объявить переменную следующим образом:
и нет :
Как и в первом случае, вы можете активировать, какую реализацию внедрять, с момента ее уникальности (только один класс реализует интерфейс). Во втором случае вам нужно провести рефакторинг всего вашего кода (у новой реализации класса другое имя). Как следствие, аннотации должны находиться на интерфейсе как можно больше. Более того, для этого хорошо подходят прокси JDK: они создаются и инстанцируются при запуске приложения, поскольку тип среды выполнения известен заранее, в отличие от прокси CGlib.
источник
@Service
реализацию и автоматически настраивать интерфейс. Spring проверит наличие любого объекта, реализующего этот интерфейс.Я бы поставил
@Service
ваш класс, но поставил имя интерфейса в качестве параметра аннотации, напримерДелая это, вы получаете все преимущества и все еще можете внедрить интерфейс, но получить класс
Таким образом, ваш интерфейс не привязан к Spring framework, и вы можете изменить класс в любое время, и вам не придется обновлять все свои точки внедрения.
Поэтому, если бы я хотел изменить класс реализации, я мог бы просто аннотировать новый класс и удалить его из первого, но это все, что требуется изменить. Если вы внедрите класс, у вас будет много работы, когда вы захотите изменить класс impl.
источник
Проще говоря:
@Service - это стереотипная аннотация для уровня сервиса .
@Repository является стереотипными аннотациями для сохранения состояния слоя.
@Component - это обобщенная аннотация стереотипа, используемая для сообщения Spring о необходимости создания экземпляра объекта в контексте приложения. Можно определить любое имя для экземпляра, по умолчанию имя класса в верблюжьем регистре.
источник
Есть 5 аннотаций, которые можно использовать для создания весенних бобов. Перечислите ответы ниже.
Вам действительно нужен интерфейс? Если вы собираетесь иметь одну реализацию для каждого интерфейса службы, просто избегайте этого, используйте только класс. Конечно, если у вас нет RMI или когда требуется интерфейсный прокси.
@Repository - используйте для внедрения классов вашего слоя dao.
@Service - используйте для внедрения классов вашего уровня обслуживания. На уровне обслуживания вам также может потребоваться аннотация @Transactional для управления транзакциями db.
@Controller - используйте для контроллеров уровня внешнего интерфейса, таких как управляемые компоненты JSF, внедряемые как компоненты Spring.
@RestController - используйте для контроллеров пружинного отдыха, это поможет вам избежать каждый раз добавлять аннотации @ResponseBody и @RequestBody в ваши методы отдыха.
@Component - используйте его в любом другом случае, когда вам нужно ввести Spring bean, который не является контроллером, службой или классом dao
источник