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() в новом конструкторе, поэтому система регистрации процессора не работала.

Я передаю @AutowiredThemeManagerService к моему 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 - отличный инструмент и высоко ценится.

Другие вопросы по тегам