С помощью Spring boot framework можно ввести список компонентов в качестве зависимости. Я всегда находил использование этой функции полезным и элегантным, поэтому я делюсь своим мнением по этому вопросу. В моем примере будет использоваться Kotlin, но мы можем предположить, что он работает и в Java так же хорошо.
Наш пример решит проблему аутентификации с несколькими поставщиками: стандартная аутентификация, Facebook, Google или что-нибудь еще. Чтобы упростить задачу, мы сосредоточимся только на функции входа в систему.
Настройка поставщиков
При внедрении зависимостей мы создадим интерфейс, который будет определять компоненты для внедрения. Здесь мы будем называть этот интерфейс Login provider :
interface ILoginProvider { fun login(request: AuthRequest): Account fun supports(request: AuthRequest): Boolean }
Функция login
– это место, где происходит логика входа в систему, функция supports
отвечает за возврат, поддерживается ли объект AuthRequest каждым поставщиком или нет. Мы передаем объект Запрос авторизации в качестве аргумента для входа в систему
и поддерживает
функцию:
data class AuthRequest( val type: AuthType = AuthType.OTHER // enum : [EMAIL,FACEBOOK,OTHER] val email: String = "" val credentials: String? = null // only filled with email/password val socialToken: String? = null // only filled with FB )
Этот интерфейс будет реализован новым классом для каждого источника. Для нашего примера мы создадим Поставщик входа в систему электронной почты и Поставщик входа в Facebook (пример ниже), которые оба будут реализовывать Loginprovider .
@Service class FacebookLoginProvider() : ILoginProvider { override fun login(request: AuthRequest): Account { // TODO : implement login function } override fun supports(request: AuthRequest): Boolean { return request.type == AuthType.FACEBOOK } }
Настройка службы
Теперь пришло время внедрить этих поставщиков, и это, безусловно, самая крутая часть. При использовании Spring Boot вы можете использовать волшебную аннотацию @Autowired
для выполнения инъекции. В нашем случае мы хотим внедрить все компоненты, реализующие Login provider в нашу службу входа в систему:
@Service class LoginService() { @Autowired lateinit var loginProviders: List}
Последнее, что нужно сделать, это правильно использовать этот список поставщиков, правильно подключив каждый запрос Auth к точному поставщику: Вы можете сделать следующее:
@Service class LoginService() { @Autowired lateinit var loginProviders: Listfun login(request: AuthRequest): Account { val provider = loginProviders.firstOrNull{it.supports(request)} ?: throw Exception("Provider not found") return provider.login(request) } }
Вывод
Вводя списки поставщиков, мы можем поддерживать общность между различными источниками поставщиков. В нашем примере очень легко отключить источник (сделав supports
return false), добавить новый (добавив новый AuthType и создав нового поставщика). Это очень полезно, когда контекст представляет собой постоянно меняющийся продукт
Вы можете масштабировать этот подход до любого количества поставщиков и добавить больше логики для выбора поставщика с помощью функции supports
..
Некоторые общие функции значительно выигрывают от такого подхода, такие как аутентификация, оплата. Этот подход может быть адаптирован к любому языку или фреймворку, но я хотел подчеркнуть, насколько элегантно было использовать Spring boot framework.
Спасибо за чтение!
Оригинал: “https://dev.to/lokosama/kotlin-spring-boot-use-case-dependency-injection-of-a-list-of-services-1fcg”