Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

192
Views
Changing the Spring beans implementation at runtime

I have an Interface and multiple implementation. I'm auto wiring the interface in classes for usage. I need to choose different implementation at runtime.

public class Util {
  public void getClient();
}

Implementations

public class UtilOne implements Util {
  public void getClient() {...}
}

public class UtilTwo implements Util {
  public void getClient() {...}
}

@Configuration
public class AppConfig {
  
  @Autowired
  @Bean
  @Primary
  public Util utilOne() {
    return new UtilOne();
  }

  @Autowired
  @Bean
  public Util utilTwo() {
    return new UtilTwo();
  }

}
@Component
public class DemoService {

  @Autowired
  private Util util;
}

For some reason if we are unable to get client in UtilOne, I want to switch to UtilTwo without restarting the app. I want to change the Util object in DemoService to UtilTwo object. Property active.util will come from DB and can we updated from UI.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

It doesn't work this way - if you have a certain implementation of Util wired to, say, class SampleClass (which is a singleton) you can't really change the implementation of the Util to something different without restarting the application context.

So instead of going this way, I suggest an alternative. You say that under certain conditions that evaluate in runtime you want to switch implementations. What kind of condition it is? Is it possible to extract this condition decision logic?

If so, you can autowire a special DynamicUtil that will hold the reference to all the utils and will call the required util depending on the condition:

// represents all possible business 'runtime' outcomes
enum ConditionOutcome {
   A, B, C 
}
interface ConditionEvaluator {
   ConditionOutcome evaluate(); // when called in runtime will evaluate a condition that currently exists in the system
}

interface Util {
   void foo();
   ConditionOutcome relevantOfOutcome();
}

class Utill1Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.A;}
}
class Utill2Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.B;}
}
class Utill3Impl implements Util {
   public void foo() {...}
   public ConditionOutcome relevantOfOutcome() {return ConditionOutcome.C;}
}

class DynamicUtil {
   private final Map<ConditionOutcome, Util> possibleImpls;
   private final ConditionEvaluator evaluator;

   public class DynamicUtil(List<Util> allImplementations, ConditionEvaluator evaluator) {
      // create a map by calling the 'relevantOfOutcome' per util impl in a loop
    this.evaluator = evaluator;
   }
   
   public void foo() {
      ConditionOutcome key = evaluator.evaluate();
      // pick the relevant implementation based on evaluated key
      possibleImpls.get(key).foo();
   }
}

Now with such a design you can dynamically add new possible outcomes (along with utils that should implement them. You classes in the system will have to autowire DynamicUtil though, so effectively you'll introduce one additional level of indirection but will gain flexibility

class SampleClass { // a business class that will need to work with util capable of being changed during the runtime 
   @Autowired
   private DynamicUtil util;
   ... 
}
over 4 years ago · Santiago Trujillo Report

0

You can try approach with delegating proxy. Have a primary Util bean that is just wrapper around actual implementation and allow to change its internal delegate at runtime. In addition you can create something like manager/helper class that holds references to all actual implementation beans to simplify switching between them.

@Component
@Primary
public class DelegatingUtil implements Util {
  private Util delegate;

  public void setDelegate(Util delegate){ this.delegate = delegate; }
  public Util getDelegate(){ return delegate; }

  public void getClient() {
    return delegate.getClient();
  }
}

And where switching logic applies:

  // Use @Named or @Qualifier or any other way to obtain references to actual implementations 
  private Util defaultImpl;
  private Util fallbackImpl;

  @Autowired
  private DelegatingUtil switcher;

  public void switchToFallback(){
    this.switcher.setDelegate(this.fallbackImpl);
  }

Note, this is only schematic example, you should take care about details like bean creation order, injection with qualifiers (maybe conditional), initialization and so on.

over 4 years ago · Santiago Trujillo Report

0

Here is a simple approach based on your situation. The main idea is that read active.util property from DB by PropertyService and wrap your Utils into RouteUtil:

@Component
public class RouteUtil {

    @Autowired
    private PropertyService propertyService;  

    @Qualifier("one")
    @Autowired
    private Util utilOne;

    @Qualifier("two")
    @Autowired
    private Util utilTwo;

    public void getClient() {
        if ("one".equals(propertyService.read("active.util"))) {
            utilOne.getClient();
        } else {
            utilTwo.getClient();
        }
    }
}

and in DemoService:

@Service
public class DemoService {

  @Autowired
  private RouteUtil util;

  // RouteUtil.getClient() ...
}

You can change active.util to select which Util will be used at runtime without restarting the app.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!