【问题标题】:Spring Cloud Zuul and Groovy FiltersSpring Cloud Zuul 和 Groovy 过滤器
【发布时间】:2018-08-23 16:21:26
【问题描述】:

我有一个基于 Spring Cloud Netflix 包运行的 Zuul 网关。我还创建了一个基于 Zuul“groovy”的过滤器,如 blog here 所示。当我添加 groovy 文件时,由于 IDE / 编译器抱怨类路径上没有 groovy 库,我还必须将以下 jar 添加到我的 pom.xml 以允许将 groovy 文件编译到项目中-

<dependency>
    <groupId>org.codehaus.groovy</groupId>
    <artifactId>groovy-all</artifactId>
    <version>2.3.10</version>
</dependency>

从这里开始,我的 groovy 过滤器按预期加载,并针对 Zuul 的每个传入请求进行评估。到目前为止一切都很好,除非我尝试修改 groovy 文件,除非我重新启动服务器,否则我看不到对文件的更改是动态拾取的。

我对 Groovy 很陌生。在 Netflix Zuul 及其过滤器的上下文中,我应该怎么做才能利用 Groovy 过滤器的动态特性。来自 Netflix 的 pain Zuul 库会扫描特定目录以查找 Groovy 过滤器。 Netflix Zuul 的 Spring cloud wrapper 有类似的东西吗?

请注意,我已阅读 Spring 4 支持动态语言,如 groovy 等,但使用它需要使用 lang:groovy 等配置 XML 文件。

但是,在我的例子中——使用 Spring Cloud Netflix 库,没有 groovy 类的 XML 配置文件,我能够让 Spring Cloud / Zuul 库获取我的 groovy 类。我无法动态刷新它,想知道是否有办法做到这一点。

我确实阅读了 spring-cloud 文档,除了一条语句之外,我没有看到任何有关加载 groovy 过滤器的信息 - Zuul’s rule engine allows rules and filters to be written in essentially any JVM language, with built in support for Java and Groovy.

请指教。

【问题讨论】:

    标签: java groovy netflix-zuul spring-cloud-netflix


    【解决方案1】:

    所以,我通过查看github netflix zuul wiki 弄清楚了。

    对于遇到此问题并正在寻找简单答案的其他人,请看,我正在为您节省一些时间:)

    第 1 步 - 将 groovy-all jar 添加到类路径

    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.3.10</version>
    </dependency>
    

    第 2 步 - 使用文件夹结构将文件放置在 src/main/resources 路径中

        groovy
        └── pre
        └── route
        └── post
    

    第 3 步 - 在我的 application.yml 中配置 Groovy 过滤器路径 -

    zuul:
      groovyFiltersPath:
        - groovy/pre
        - groovy/route
        - groovy/post
    

    第 4 步 - 在 Zuul Spring Boot 应用程序中注入 yaml 配置

    @Component
    @EnableConfigurationProperties
    @ConfigurationProperties(prefix = "zuul")
    public class CustomPathZuulFilterConfig {
    
        private List<String> groovyFiltersPath;
    
        public List<String> getGroovyFiltersPath() {
            return groovyFiltersPath;
        }
    
        public void setGroovyFiltersPath(List<String> groovyFiltersPath) {
            this.groovyFiltersPath = groovyFiltersPath;
        }
    }
    

    第 5 步 - 最后,初始化 Groovy 过滤器加载器和文件管理器

    @Component
    public class GroovyFiltersInitializer {
    
        private Logger logger = LoggerFactory.getLogger(GroovyFiltersInitializer.class);
    
        @Autowired
        private CustomPathZuulFilterConfig config;
    
        @PostConstruct
        private void initGroovyFilters() throws Exception {
    
            List<String> groovyFiltersPath = config.getGroovyFiltersPath();
    
            if(groovyFiltersPath == null || groovyFiltersPath.size() == 0) {
                return;
            }
    
            FilterLoader.getInstance().setCompiler(new GroovyCompiler());
            FilterFileManager.setFilenameFilter(new GroovyFileFilter());
    
            String[] filterDirectoryList = groovyFiltersPath.toArray(new String[0]);
            FilterFileManager.init(5, filterDirectoryList);
    
            logger.info("Groovy Filter file manager started");
        }
    }
    

    现在,对 groovy 过滤器的任何更改都应动态获取。

    特定于 IntelliJ 用户 - 要检查对 groovy 文件的更改是否被拾取,您需要更改调试器“out”目录下的文件,而不是 src/main/resources/groovy 目录下的文件。那是因为,应用程序运行基于“out”目录中的代码。但是,要调试您的更改 - 您必须在“out”和 src/main/resources/groovy 目录中进行更改,因为 IntelliJ 在应用程序运行时不会将文件复制到“out”。希望这会有所帮助。

    祝你好运!

    【讨论】:

    • 这是个好东西。问题:GroovyFiltersInitializer 是如何连接到您的应用程序的?它是否会自动加载/实例化,即使没有通过@Autowire/@Inject 在您的应用中的任何地方引用
    • @dexter 我记得将它自动装配到我的应用程序类文件之一以确保实例化。
    • 谢谢@Satya,这就是我最终所做的。
    猜你喜欢
    • 2016-07-11
    • 2020-04-15
    • 2023-03-04
    • 2018-08-06
    • 2016-05-27
    • 2015-11-13
    • 2017-06-17
    • 2017-09-29
    • 2019-05-26
    相关资源
    最近更新 更多