Size: a a a

Spring Framework and more

2019 March 21

VP

Vitaliy [Optimus Prime] Pomaz in Spring Framework and more
Кейс: есть обект Юзер (токен, логин, мыло и тд) - по токену нужно делать кросБД запросы по вытягиванию даты - список доступных полигонов, координаты, история погоды, показатели грунта и т.д.

при чем Одно тело, много запросов разосрано по всему апликейшну
источник

VP

Vitaliy [Optimus Prime] Pomaz in Spring Framework and more
Pavel Bukhmatov
Ну кажется, что это можно делать через ApplicationContextAware (или BeanFactoryAware) типо вот так:

public class BeanRegistrator implements ApplicationContextAware {

private ConfigurableListableBeanFactory beanFactory;
   
   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       var context = (ConfigurableApplicationContext) applicationContext;
       this.beanFactory = context.getBeanFactory();
   }
   
   public void registerSingletonBean(String name, Object singleton) {
       this.beanFactory.registerSingleton(name, singleton);
   }
}

Но если честно, это выглядит как довольно отвратительная затея и мне кажется что-то может пойти не так. Надо тестировать)
А какой юз. кейс? Может можно что-нибудь попроще?
Если вопрос именно о рантайме после полной инициализации контекста (т.е. когда уже отработали все BeanFactoryPostProcessor/BeanFactoryProcessor) то я не могу придумать юз кейсы, как это могло бы пригодиться)
спасибо, затестим))
источник

PB

Pavel Bukhmatov in Spring Framework and more
Vitaliy [Optimus Prime] Pomaz
Кейс: есть обект Юзер (токен, логин, мыло и тд) - по токену нужно делать кросБД запросы по вытягиванию даты - список доступных полигонов, координаты, история погоды, показатели грунта и т.д.

при чем Одно тело, много запросов разосрано по всему апликейшну
1 запрос от некого клиента, преобразуются во много запросов внутри приложения, собираются в 1 мега-ответ и потом отправляются клиенту? Я так понял?
Не вижу что-то как тут поможет запихнуть пользователя или его данные в контекст)
источник

VP

Vitaliy [Optimus Prime] Pomaz in Spring Framework and more
Почти, только не один мега ответ, а когда он гуляет по приложению, ему подливаються данные с БД в разных углах ресурса((
источник

PB

Pavel Bukhmatov in Spring Framework and more
Так у него же токен и бекенд stateless (если мысленно вычеркивать БД). Какую информацию тут можно хранить в контексте?
Он делает запрос - по токену определяется кто он, ему дается ответ
источник

PB

Pavel Bukhmatov in Spring Framework and more
Кстати вот еще дяденька делает сингтон бин, хранящий внутри prototype бины, создаваемые в рантайме. Но это не настоящие бины, судя по всему. https://stackoverflow.com/questions/27809838/how-to-instantiate-spring-managed-beans-at-runtime
Я правд не понял зачем, но надо человеку видимо)
источник

VP

Vitaliy [Optimus Prime] Pomaz in Spring Framework and more
Pavel Bukhmatov
Кстати вот еще дяденька делает сингтон бин, хранящий внутри prototype бины, создаваемые в рантайме. Но это не настоящие бины, судя по всему. https://stackoverflow.com/questions/27809838/how-to-instantiate-spring-managed-beans-at-runtime
Я правд не понял зачем, но надо человеку видимо)
Видимо надо)
Спасибо!
Извини, наху..вертил с условиями задачи... Уже сам начал путаться, что хотел((
источник

PB

Pavel Bukhmatov in Spring Framework and more
ну тут можно очень быстро наговнокодить и потом пожалеть.
Возможно в твоем кейсе достаточно создать свой prototype бин. Или вообще через threadlocal решить проблему. В крайнем случае - создать свой скоуп.
Но впихивать бины в рантайме мне кажется одной из таких шаманских техних, которые либо не надо использовать, либо ты точно знаешь, что делаешь)
источник

PB

Pavel Bukhmatov in Spring Framework and more
Вот чуваки в далеком 2014 году еще что-то подобное делали. https://habr.com/ru/post/225397/
Но там тоже как-то сложно. Чутье подсказывает, что элегантное решение есть где-то рядом в области кастомных скоупов. Может быть threadlocal.
Ох уж этот ентерпрайз
источник

MC

Maksim Chesnokov in Spring Framework and more
testCompile('org.springframework.boot:spring-boot-starter-test')
   compile('me.ramswaroop.jbot:jbot:3.0.2')
   compile('org.apache.httpcomponents:httpclient:4.5.6')
   compile('com.fasterxml.jackson.core:jackson-databind:2.9.6')
   compile('com.ullink.slack:simpleslackapi:1.2.0')
   compile('com.google.api-client:google-api-client:1.28.0')
   compile('com.google.oauth-client:google-oauth-client-jetty:1.23.0')
   compile('com.google.apis:google-api-services-sheets:v4-rev568-1.25.0')
источник

MC

Maksim Chesnokov in Spring Framework and more
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
источник

MC

Maksim Chesnokov in Spring Framework and more
spring-boot-starter-web и tomcat не помогают
источник

MC

Maksim Chesnokov in Spring Framework and more
подозреваю на то что каталина в зависимостях и томкат из спринга конфликтуют
источник

MC

Maksim Chesnokov in Spring Framework and more
как такое пофиксить?
источник

PB

Pavel Bukhmatov in Spring Framework and more
Maksim Chesnokov
Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost]]
Если честно, ничего не понятно.
Что это за зависимости?
Что происходит? Просто старт boot приложения и сразу падение?
Можно ли воспроизвести проблему с нуля в отдельном boot приложении?
И это явно не весь страктрейс.
источник

MC

Maksim Chesnokov in Spring Framework and more
Pavel Bukhmatov
Если честно, ничего не понятно.
Что это за зависимости?
Что происходит? Просто старт boot приложения и сразу падение?
Можно ли воспроизвести проблему с нуля в отдельном boot приложении?
И это явно не весь страктрейс.
старт и сразу падение, было пустое boot приложение, добавил зависимости из https://developers.google.com/sheets/api/quickstart/java , посыпались ошибки
источник

MC

Maksim Chesnokov in Spring Framework and more
без google-oauth-client-jetty валится там где и должно быть, поэтому думаю jetty с tomcat из спринга конфликтует
источник

PB

Pavel Bukhmatov in Spring Framework and more
Maksim Chesnokov
без google-oauth-client-jetty валится там где и должно быть, поэтому думаю jetty с tomcat из спринга конфликтует
Похоже на то. LocalServerReceiver
> OAuth 2.0 verification code receiver that runs a Jetty server on a free port, waiting for a redirect with the verification code.
Можно попробовать либо заменить клиент (там в разделе Notes есть ссылка на то, как это делать  https://developers.google.com/identity/protocols/OAuth2WebServer ),
либо все приложение стартовать на jetty
источник

PB

Pavel Bukhmatov in Spring Framework and more
И в интернетах есть ровно такая же проблема)
https://stackoverflow.com/questions/48340422/spring-boot-conflicting-gradle-dependancies-google-oauth-client
источник

MC

Maksim Chesnokov in Spring Framework and more
спасибо,     testCompile('org.springframework.boot:spring-boot-starter-jetty')
решил проблему
источник