У меня есть приложение Spring Boot, которое я пытаюсь запустить в кластере Apache Flink. Это стандартное приложение Spring Boot с основным классом, аннотированным с помощью @SpringBootApplication (фрагмент кода добавлен позже в этот вопрос).
Когда я попытался запустить Spring Загрузив приложение в автономном кластере Apache Flink с помощью следующей команды, я сразу же начал сталкиваться с проблемами с автоматическим подключением компонентов. Flink не удалось отключить bean-компоненты, подключенные автоматически.
./bin/flink run
examples/streaming/my-springboot-function. jar
В ходе дальнейших исследований я обнаружил, что функции flink выполняются в TaskExecutors, и когда это происходит, Flink сначала серализует функцию и затем десериализуйте его в TaskExecutor. На этом этапе зависимости будут иметь значение null и не будут автоматически подключаться автоматически.
Чтобы решить эту проблему, я просто создал свой собственный контекст Spring и вызвал его в открытом виде метод моей функции и автоматическое подключение bean-компонентов было запущено, как и ожидалось.
Но текущая проблема, с которой я сейчас сталкиваюсь, заключается в том, что Spring Boot не может сопоставить аргументы командной строки с @Value поля, отмеченные аннотацией.
Код и подробности
Пользовательский контекст Spring:
Код: Выделить всё
public class CustomSpringContext {
private transient final ConcurrentHashMap springContext;
public CustomSpringContext() {
springContext = new ConcurrentHashMap();
}
public ApplicationContext getContext(String configurationPackageName) {
return springContext.computeIfAbsent(configurationPackageName, AnnotationConfigApplicationContext::new);
}
public T autowiredBean(T bean, String configurationPackageName) {
AnnotationConfigApplicationContext context = getContext(configurationPackageName);
AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
factory.autowireBean(bean);
return bean;
}
}
Код: Выделить всё
@Component
public class TransformFunction extends RichMapFunction implements Serializable {
@Autowired
private transient CacheDao cacheDao;
@Autowired
private transient ProcessController processController;
public String map(AuditRecord auditRecord) throws Exception {
//Some business logic
}
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
//Autowire the dependent beans in this class
new CustomSpringContext().autowiredBean(this, "com.mypackage");
}
}
Но я теперь я столкнулся с проблемой: если я передаю в свою программу какие-либо аргументы командной строки, они не внедряются в свойства, отмеченные @Value. В типичном приложении Spring Boot свойства, помеченные как @Value, также могут быть заполнены через командную строку, а не обязательно из файла applicaiton.properites. Но здесь, похоже, это не так.
Например, в моем приложении есть следующий класс конфигурации. Он использует @Value :
Код: Выделить всё
@Configuration
@ComponentScan(basePackages = "com.mypackage")
public class TaskApplicationConfig {
@Value("commandLineArgument");
private String commandLineArgument;
//other bean configurations etc
}
java.lang.IllegalArgumentException: не удалось разрешить заполнитель «commandLineArgument» в строковом значении [${commandLineArgument}]< /p>
Я немного покопался и знаю, почему это происходит. В типичном приложении Spring Boot мы реализуем интерфейс ApplicationRunner в нашем основном классе и переопределяем метод run. Этот метод run вводит аргументы командной строки в контекст, который затем доступен через аннотации @Value. Пример:
Код: Выделить всё
@SpringBootApplication
public class TaskApplication implements ApplicationRunner {
public static void main(String[] args) throws Exception {
SpringApplication.run(TaskApplication .class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception {
//call some business logic
}
}
Код: Выделить всё
TransformFunctionКак решить эту проблему?
Подробнее здесь: https://stackoverflow.com/questions/772 ... ble-to-spr
Мобильная версия