6

I use spring boot in a J2SE app.

I have some constant data, such as a map, indicating a HandlerClass to process one operation Type.

The map relation is not changed, so I want to config it in application.yml

I try this:

info:
  modify_nodeip: omm.task.impl.ModifyNodeIpHandler

But the map is only can be recognized as Map<String,String>, How can I inject the map as Map<Enum,Class>?

Thank you!

Updated: I followed @cfrick instruction, but it doen't work.

application.yml

config:
    optHandlerMap:
        modify_oms_nodeip: 'omm.task.opthandler.impl.ModifyOMSNodeIpHandler'

TestConfiguration:

@Configuration
@ConfigurationProperties(prefix = "config")
public class TestConfiguration
{

    Map<OperationType,OptHandler> optHandlerMap; // here we store the handlers, same name in yaml
    TestConfiguration() {}

}

and the main func used the configuration

@Autowired
private TestConfiguration testConfiguration;

what's wrong with that? But it doesn't work, optHandlerMap in testConfiguration is null.

NingLee
  • 1,477
  • 2
  • 17
  • 26
  • `modify_oms_nodeip:'` is most likely wrong (`:'`) – cfrick Oct 27 '14 at 09:18
  • I add a space after `:` but it still dosn't work :-( Need the `ModifyOMSNodeIpHandler` be instanced? I only have a `@Component` in `ModifyOMSNodeIpHandler`. – NingLee Oct 27 '14 at 09:23
  • 1
    Your original question was for `Map`. `OptHandler` would be an instance. Otherwise you can set the loglevel of `org.springframework.core.env` to `DEBUG` to get hopefully more insight. – cfrick Oct 27 '14 at 09:26

3 Answers3

4

You can play a trick like this:

In your TestConfiguration, define a Map<String,String>, and getter.

then provide a Map<Operator,Handler> getXXXX() function, in this function, convert the Map<String,String> to Map<Operator,Handler>.

Maybe you need to use reflect to new a instance.

By the way, you can use Maps.transform() in Guava to perform the conversion.

shangyin
  • 526
  • 1
  • 4
  • 14
0

You write your own settings and annotate as @ConfigurationProperties (see 21.6 Typesafe Configuration Properties)

@Component
@ConfigurationProperties(prefix="cfg") // the root in my yaml
class HandlerConfiguration {
    public enum Handler { Handler1, Handler2 } // enum 
    Map<Handler,Class> handlers // here we store the handlers, same name in yaml
    HandlerConfiguration() {}
}

Then my application.yaml looks like this:

cfg:
  handlers:
    Handler1: 'app.Handler1'

And accessing it like this:

def ctx = SpringApplication.run(Application, args)
ctx.getBean(HandlerConfiguration).with{
    assert handlers.size()==1 // there is the one
    assert handlers[HandlerConfiguration.Handler.Handler1] // it's key is the enum
    assert handlers[HandlerConfiguration.Handler.Handler1] == Handler1 // its value is the actual class
    handlers[HandlerConfiguration.Handler.Handler1].newInstance().run()
}

(app.Handler1 is just some random class I put there, all this is in the same package (app))

cfrick
  • 35,203
  • 6
  • 56
  • 68
  • I have tried, but It doesn't work. `config: optHandlerMap: modify_oms_nodeip:'omm.task.opthandler.impl.ModifyOMSNodeIpHandler'` the TestConfiguration:`@Configuration @ConfigurationProperties(prefix = "config") public class TestConfiguration { Map optHandlerMap; // here we store the handlers, same name in yaml TestConfiguration() {} }` and the usage ` @Autowired private TestConfiguration testConfiguration;` – NingLee Oct 27 '14 at 09:09
  • @NingLee you can update your test code in the question. – shangyin Oct 27 '14 at 09:11
  • @NingLee a) `modify_oms_nodeip:'` is invalid yaml (`:'`); b) **what** does not work... errors? exceptions? – cfrick Oct 27 '14 at 09:12
  • @cfrick I updated in the question, and I add the `space` after `:`. – NingLee Oct 27 '14 at 09:18
0

just enable config spring.data.rest.enable-enum-translation (Spring document) and Spring will do the trick