Wro4j:从自定义后处理器

时间:2016-01-16 23:15:06

标签: spring wro4j

我已经在wro4j文档的帮助下成功实现了自定义后处理器过滤器。

它的工作是为一组SASS文件生成并预先添加SASS变量,然后将这些文件传递给rubySassCss过滤器以进行转换,并且它可以很好地完成这项工作。

问题在于,我希望将确定SASS变量的工作交给Spring管理的自定义ThemeManager @Service。我没有考虑到过滤器无法看到自动连接的@Service,但似乎是这种情况。

当我@Autowire @Service进入控制器时,它工作正常,但是当我尝试使用过滤器时,我会尝试使用它时获得NPE。

有没有办法让过滤器看到@Service,或者我接近错误的方式?

感谢您的帮助。

更新

它从很多角度进行了一些操作和攻击,但我似乎已成功将我的themeManagerService自动装配到我有我的WRO filterRegistrationBean bean的app配置中。然后我将themeManagerService bean作为第二个参数传递给我的自定义ConfigurableWroManagerFactory。

生活在自定义WroManagerFactory中是对自定义UriLocator的引用,它将themeManagerService作为参数。自定义UriLocator由包含组内任意关键字的CSS资源调用。

新的UriLocator能够根据themeManagerService提供的内容生成ByteArrayInputStream并将其传递给管道。

简单。

当这种方法平息/失败时,我会跟进。

1 个答案:

答案 0 :(得分:1)

最后,我能够将Spring托管的ThemeManagerService直接提供给自定义后期处理器,而不是依赖于自定义UriLocator。我早就试过了,但是忘了在新构造函数中调用super(),因此处理器注册系统崩溃了。

我在注册WRO bean时将@Autowired ThemeManagerService传递给我的CustomConfigurableWroManagerFactory

@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是一个很棒的工具,非常感谢。