Я пытаюсь использовать ftp-inbound-adapter для опроса файлов на основе текущей даты. И мой входящий адаптер использует фильтр, который относится к bean myfilter. Проблема здесь в том, что текущая дата инициализируется при запуске и не обрабатывается динамически..я хочу получать текущую дату для каждого нового сообщения
<int-ftp:inbound-channel-adapter id = "ftpInbound"
channel = "ftpChannel"
session-factory = "ftpsClientFactory"
filter = "myFilter"
</int-ftp:inbound-channel-adapter>
<bean id = "myFilter" class = "org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter" scope = "prototype">
<constructor-arg value = "#{T(java.time.LocalDateTime).now().format(T(java.time.format.DateTimeFormatter).ofPattern('MMddyy'))}.(xls|xlsx)"/>
<aop:scoped-proxy/>
</bean>
ОБНОВИТЬ
Я изменил с этого
<bean id = "currentDate" class = "java.util.Date" factory-bean = "fastDateFormat"
scope = "prototype" factory-method = "format" >
<aop:scoped-proxy/>
<constructor-arg>
<bean class = "java.util.Date" />
</constructor-arg>
</bean>
<bean id = "myFilter" class = "org.springframework.integration.ftp.filters.FtpRegexPatternFileListFilter" scope = "prototype">
<constructor-arg value = "#{currentDate}.(xls|xlsx)"/>
</bean>
И мой входящий адаптер использует фильтр, который ссылается на bean myFilter .. Проблема здесь в том, что текущая дата инициализируется при запуске и не обрабатывается динамически .. Я хотел бы получать текущую дату для каждого нового сообщения
@AhsanShah: Я пробовал ... Это не работает.
Это невозможно с вашей текущей конфигурацией, потому что этот filter
- это просто bean-компонент singleton
, созданный только один раз при запуске, и ваш currentDate
для инъекции тоже только один раз.
Вы можете попытаться добавить <aop:scoped-proxy/>
в определение вашего bean-компонента currentDate
: https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans-factory-scopes-other-injection, но я бы посоветовал вставить BeanFactorty
в ваш filter
и вызывать getBean("currentDate", Date.class)
каждый раз, когда вам понадобится новый экземпляр этого прототипа.
ОБНОВИТЬ
Вы вводите BeanFactory
в свой filter
вместо этого bean-компонента currentDate
. И затем, когда вызывается логика фильтра, вы выполняете Date currentDate = this.beanFactory.getBean("currentDate", Date.class);
.
ОБНОВЛЕНИЕ2
Вот что, на мой взгляд, должно сработать для вас:
public class DynamicRegexPatternFilter extends AbstractFileListFilter<File> {
@Autowired
private BeanFactory beanFactory;
@Override
public boolean accept(File file) {
return Pattern.compile(this.beanFactory.getBean("currentDate", String.class) + ".(xls|xlsx)")
.matcher(file.getName())
.matches();
}
}
Я попытался добавить <aop: scoped-proxy /> в свой bean-компонент currentDate. При запуске все еще загружается дата. Каким будет другой вариант, кроме текущей конфигурации, которую я использую?
См. ОБНОВЛЕНИЕ в моем ответе, пожалуйста.
Покажите свой код фильтра, и я внесу в него соответствующие изменения.
Пожалуйста, отредактируйте свой вопрос с правильным форматированием кода. В комментариях это не читается
Я не вижу ссылки на bean-компонент currentDate
в вашем определении bean-компонента myFilter
. Также я просил вас поместить <aop:scoped-proxy/>
вместо компонента currentDate
, а не filter
. Также prototype
не будет работать с компонентом filter
. Он действительно будет создан только один раз для этого <int-ftp:inbound-channel-adapter
. Вам обязательно понадобится собственный FileListFilter
для такой нестандартной логики.
Обновил вопрос
Нет, этот <constructor-arg value = "#{currentDate}.(xls|xlsx)"/>
по-прежнему работать не будет. На самом деле вы разрешаете bean-компонент только один раз при запуске. Это выражение не вычисляется каждый раз. Как я уже сказал: вам нужен собственный FileListFilter
для построения шаблона в коде Java для каждого входящего файла.
<bean id = "myFilter" class = "package.FileNamePattern" scope = "prototype"> </bean> А у настраиваемого класса есть что-то вроде открытого класса FileNamePattern {@Autowired BeanFactory beanFactory; общедоступный FileNamePattern () {Date date = this.beanFactory.getBean ("currentDate", Date.class); }}
Звучит намного лучше!
: Но как эта дата отображается обратно в myFilter. И как мы можем использовать это значение даты обратно в нашем фильтре? .. Я не могу перейти по ссылке .. Как все это работает в фоновом режиме
Пожалуйста, найдите UPDATE2 в моем ответе.
<bean id = "myFilter" class = "package.DynamicRegexPatternFilter" scope = "prototype"> </bean> <bean id = "fastDateFormat" class = "org.apache.commons.lang.time.FastDateFormat" scope = "prototype "factory-method = " getInstance "> <constructor-arg value = " MMddyy "/> </bean> <bean id = " currentDate "class = " java.util.Date "factory-bean = " fastDateFormat "scope = " prototype "factory-method = " format "> <constructor-arg> <bean class = " java.util.Date "scope = " prototype "/> </constructor-arg> </bean>
Я думаю, вы не можете изменить системную дату для уже запущенной JVM. Это уже выходит за рамки нашей текущей проблемы ...
также измените bean-компонент фильтра на "прототип"