Home > Enterprise >  Spring conditionally require bean only if profile is active
Spring conditionally require bean only if profile is active

Time:08-25

I have a class which is disabled based on @Profile. I want to use it inside another class that is not conditional on the same profile:

@Component
@Profile("!local")
public class NotAlwaysExistingClass {

    public void doThing() {
    ...
    }
}

public class AlwaysExistingClass {
    
    @Autowired(required=true)
    NotAlwaysExistingClass notAlwaysExisting;

    // Impossible for this to happen if profile is "local"
    public void notAlwaysDoneThing() {
        notAlwaysExisting.doThing();
    }
    ...
}

I don't want to set the @Autowired(required=false) in all cases. Is it possible to disable the requirement only if a certain profile is active? I want to do this to make it more convenient to occasionally run the code locally, but without compromising the application or making major changes to the class structure.

CodePudding user response:

I agree with @xerx593's #1 but you could also change that a little. You could extract an interface and make the class depending on it use it via an interface. Then you would have 2 beans that implement that interface and only available at a given time via @Profile selection. Remember @Autowired is by type by default.

Really this issue is similar (or the same) to having a couple of profiles for various needs of a datasource for example. In my projects, the local profile points to a local DB, the regular one points to some cloud db via env variables or whatever, and then I have a "cicd" profile for integration tests and those use a spun up H2 DB.

CodePudding user response:

"Smart" (tricky) (?) approach:

NO-OP Bean/Profile ;)

  1. Introduce an other "bean" (or "class"), which:
  • extends NotAlwaysExistingClass
  • takes @Profile("local") (so the logical complement of the "non-local" profile)
  • overrides doThing(), but with no-op/cheap/only logging code.
  1. Done.
  • you don't need (further) refactorings
  • you can leave the required attribute (one of the profiles will always strike)
  • in "non-local" profile, you get the right bean
  • in "local" profile: nice logging/no-op :)
  • Related