Wro4j: доступ к Spring @Service из пользовательского постпроцессора
Я успешно реализовал пользовательский постпроцессорный фильтр с помощью документации wro4j.
Его работа заключается в создании и добавлении переменных SASS к группе файлов SASS, которые затем передаются в фильтр rubySassCss для транспаранта, и он хорошо справляется с этой задачей.
Проблема в том, что я хотел передать работу по определению переменных SASS на заказ. ThemeManager
@Service
управляется весной. Я не учел, что фильтр не сможет увидеть автосвязанный @Service, но, похоже, это так.
Когда я @Autowire
@Service
в контроллер, он работает нормально, но когда я пытаюсь сделать то же самое с фильтром, я получаю NPE при попытке его использовать.
Есть ли способ сделать @Service
видно по фильтрам или я к этому подхожу не так?
Спасибо за любую помощь.
ОБНОВИТЬ:
На это потребовалось некоторое количество действий и атак с разных сторон, но я, кажется, добился успеха с автоматическим подключением моего themeManagerService в конфигурацию приложения, где у меня есть bean-компонент WRO filterRegistrationBean. Затем я передаю bean-компонент themeManagerService в качестве второго аргумента в мой пользовательский ConfigurableWroManagerFactory.
Жизнь в пользовательском WroManagerFactory - это ссылка на пользовательский UriLocator, который принимает этот themeManagerService в качестве аргумента. Пользовательский UriLocator вызывается ресурсом CSS, содержащим произвольное ключевое слово в группе.
Новый UriLocator может генерировать ByteArrayInputStream из того, что предоставляет ему themeManagerService, и передавать его в конвейер.
Просто.
Я буду следить, когда этот подход потерпит неудачу.
1 ответ
В итоге я смог предоставить управляемый пружиной ThemeManagerService непосредственно в пользовательский постпроцессор, а не полагаться на пользовательский UriLocator. Я пробовал это на ранних этапах, но забыл вызвать super() в новом конструкторе, поэтому система регистрации процессора не работала.
Я передаю @Autowired
ThemeManagerService
к моему CustomConfigurableWroManagerFactory
при регистрации bean-компонента WRO:
@Autowired
ThemeManagerService themeManagerService;
@Bean
FilterRegistrationBean webResourceOptimizer(Environment env) {
FilterRegistrationBean fr = new FilterRegistrationBean();
ConfigurableWroFilter filter = new ConfigurableWroFilter();
Properties props = buildWroProperties(env);
filter.setProperties(props);
//The overridden constructor passes ThemeManager along
filter.setWroManagerFactory(new CustomConfigurableWroManagerFactory(props,themeManagerService));
filter.setProperties(props);
fr.setFilter(filter);
fr.addUrlPatterns("/wro/*");
return fr;
}
Конструктор инъекций ThemeManagerService
в CustomConfigurableWroManagerFactory
означает, что он может быть передан пользовательскому постпроцессору, так как он зарегистрирован contributePostProcessors
:
public class CustomConfigurableWroManagerFactory extends Wro4jCustomXmlModelManagerFactory {
private ThemeManagerService themeManagerService;
public CustomConfigurableWroManagerFactory(Properties props,ThemeManagerService themeManagerService) {
//forgetting to call super derailed me early on
super(props);
this.themeManagerService = themeManagerService;
}
@Override
protected void contributePostProcessors(Map<String, ResourcePostProcessor> map) {
//ThemeManagerService is provided as the custom processor is registered
map.put("repoPostProcessor", new RepoPostProcessor(themeManagerService));
}
}
Теперь почтовый процессор имеет доступ к ThemeManagerService
:
@SupportedResourceType(ResourceType.CSS)
public class RepoPostProcessor implements ResourcePostProcessor {
private ThemeManagerService themeManagerService;
public RepoPostProcessor(ThemeManagerService themeManagerService) {
super();
this.themeManagerService = themeManagerService;
}
public void process(final Reader reader, final Writer writer) throws IOException {
String resourceText = "/* The custom PostProcessor fetched the following SASS vars from the ThemeManagerService: */\n\n";
resourceText += themeManagerService.getFormattedProperties();
writer.append(resourceText);
//read in the merged SCSS and add it after the custom content
writer.append(IOUtils.toString(reader));
reader.close();
writer.close();
}
}
Этот подход работает, как ожидалось / задумано до сих пор. Надеюсь, это пригодится кому-то еще.
Wro4j - отличный инструмент и высоко ценится.