【问题标题】:SpringBoot microservice How to set properties in application context using java configurationSpringBoot微服务如何使用java配置在应用程序上下文中设置属性
【发布时间】:2018-07-26 07:55:10
【问题描述】:

我有一个基于 Java 的配置的 spring-boot 微服务。现在有一个身份验证令牌容器,我需要调用它来获取访问令牌。该身份验证令牌库有一个像这样的类。请注意,AuthServletContextListener 类来自我无法修改的第三方 jar 文件。

public class AuthServletContextListener implements ServletContextListener {
    public void contextInitialized(ServletContextEvent arg0) {
        try {
            ServletContext e = arg0.getServletContext();
            Properties config = new Properties();
            this.addProp(config, e, "auth.token.url", "Token Service URL");
            this.addProp(config, e, "auth.system.username", "System Username");
            this.addProp(config, e, "cauth.system.password", "System Password");
            TokenContainer.init(config);
        } catch (IOException arg3) {
            arg3.printStackTrace();
        }

    }


    private void addProp(Properties config, ServletContext context, String propName, String descrip) {
        String propVal = (String) context.getAttribute(propName);
        if (StringUtils.isEmpty(propVal)) {
            propVal = context.getInitParameter(propName);
        }

        if (StringUtils.isNotEmpty(propVal)) {
            config.put(propName, propVal);
        } else {
            throw new RuntimeException("error: ");
        }
    }
}

AuthContextListener 有一个自动寻找应用程序启动事件的注解。如果包含上述上下文参数,这将自动启动容器正确设置。然后我可以像这样通过该容器获取令牌:

TokenContainer.getSystemToken() 

如果上面的上下文参数包含在 web.xml 中,这将成功初始化,如下所示:

<context-param>
   <param-name>auth.system.username</param-name>
   <param-value>UserName</param-value>
</context-param> 

可以通过使用以下信息创建一个 Spring bean 来执行与上述相同的应用程序上下文配置:

<bean>
    <property name="attributes">
        <map>
            <entry key="auth.token.url" value="${auth.token.url}"/>
            <entry key="auth.system.username" value="${auth.system.username}"/>
            <entry key="auth.system.password" value="${auth.system.password}"/>
        </map>
    </property>
</bean>

我的问题是如何在最新的 Spring Boot 应用程序中使用基于 Java 的配置来实现相同的目标。我只有application.yml 文件,其中包含身份验证端点、用户名和密码值。我尝试使用@Configuration bean 但没有运气。如何在应用程序上下文中设置这三个道具并让该侦听器为我自动启动。

【问题讨论】:

  • 不要使用监听器...只需创建一个与常规 Spring Bean 功能相同但功能相同的类。如果您真的想使用它,请创建另一个 ServletContextListener,它会在 servlet 上下文中公开属性并确保它在此侦听器之前执行。
  • @Deinum 一些身份验证库供应商已将侦听器和容器作为 jar 文件提供给我。所以他们在容器内缓存令牌。所以听众是我到达那里的唯一希望。我也无权更改侦听器,因为它是 auth lib 供应商提供的 jar。
  • 为什么...如果您在常规 Spring bean 中实现相同的逻辑,它仍然可以工作...您只需将这 4 行代码放入 Spring bean 并从 Spring 加载属性。 ..(但请参阅我的回答,这应该会有所帮助)。
  • 好的,两个都试试。谢谢。

标签: java spring spring-boot microservices applicationcontext


【解决方案1】:

在您的 application.yml 或 application.properties 中为您的 auth url 添加一组:

#Example for application.properties
auth.token.url = http:\\...

然后在你的配置类中配置你的占位符,这样你就可以读取你的属性值:

@Configuration
public class Config {
        @Bean
        public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
            propertySourcesPlaceholderConfigurer.setLocations(new ClassPathResource("application.properties"));//or application.yml
            return propertySourcesPlaceholderConfigurer;
        }

    }

然后在你的 AuthServletContextListener 类中:添加这个

public class AuthServletContextListener implements ServletContextListener {

  @Value("${auth.token.url}")
  private String authUrl ;

    public void contextInitialized(ServletContextEvent arg0) {
        try {
            ServletContext e = arg0.getServletContext();
            Properties config = new Properties();
            this.addProp(config, e, "auth.token.url", authUrl);
            this.addProp(config, e, "auth.system.username", "System Username");
            this.addProp(config, e, "cauth.system.password", "System Password");
            TokenContainer.init(config);
        } catch (IOException arg3) {
            arg3.printStackTrace();
        }

    }


    private void addProp(Properties config, ServletContext context, String propName, String descrip) {
        String propVal = (String) context.getAttribute(propName);
        if (StringUtils.isEmpty(propVal)) {
            propVal = context.getInitParameter(propName);
        }

        if (StringUtils.isNotEmpty(propVal)) {
            config.put(propName, propVal);
        } else {
            throw new RuntimeException("error: ");
        }
    }
}

【讨论】:

  • 我无法控制AuthServletContextListener 类。这是由某个第三方编写的,我只是通过 mvn 依赖获得它。
【解决方案2】:

将以下内容添加到您的application.properties

server.servlet.context-parameters.auth.token.url=<your-value>
server.servlet.context-parameters.auth.system.username=<your-value>
server.servlet.context-parameters.auth.system.password=<your-value>

这会将值公开为上下文参数。

【讨论】:

  • 谢谢,我会试一试并回复您。
  • 我喜欢这个解决方案,等待您的支持@Ravinda Ranwala
猜你喜欢
  • 1970-01-01
  • 2021-11-13
  • 2020-07-03
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-24
相关资源
最近更新 更多