Udo Held Udo Held - 6 months ago 24
Java Question

Spring default wiring with Profile

I've got two beans. Both implement the mailing function. One is only working when it is deployed to an application server. The other one is used for testing.

We have profile for each developer and environment. I want to wire the testing bean only when actually testing. The other bean should be used when not testing. How can I archive this?

@Component
@Profile("localtest")
public class OfflineMail implements Mailing {}


Solution approaches:

Using "default" I read this somewhere, but there seems to be no fall-back to "default" for a profile like "dev":

@Component
@Profile("default")
public class OnlineMail implements Mailing {}


-> Exception for no bean for wiring found.

Leaving the profile out:

@Component
public class OnlineMail implements Mailing {}


-> Throws a unique exception when running the "localtest" profile.

Adding all profiles:

@Component
@Profile("prod")
@Profile("integration")
@Profile("test")
@Profile("dev1")
@Profile("dev2")
@Profile("dev3")
...
public class OnlineMail implements Mailing {}


This is actually working, however our devs aren't numbered they use "dev<WindowsLogin>" and adding the profiles, may work for one bean, but one will get into trouble when using it for several beans as this definitely gets ugly.

Using something like @Profile("!localtest") doesn't seem to work as well.

Does anyone know a nicer way to get a "wire by default if no specific bean is found"?

Answer

I finally found an easy solution.

The online mail is just wired by default.

@Component
public class OnlineMail implements Mailing {}

Using the @Primary annotation the offline mail takes precedence over the OnlineMail and avoids the Unique exception.

@Component
@Profile("localtest")
@Primary
public class OfflineMail implements Mailing {}
Comments