webentwicklung-frage-antwort-db.com.de

Spring Bean mit Laufzeitkonstruktorargumenten

Ich möchte ein Spring Bean in Spring Java configuration mit einigen zur Laufzeit übergebenen Konstruktorargumenten erstellen. Ich habe Folgendes erstellt Java config, in der es eine Bean gibt fixedLengthReport, die einige Argumente im Konstruktor erwartet.

@Configuration
public class AppConfig {

    @Autowrire
    Dao dao;

    @Bean
    @Scope(value = "prototype")
    **//SourceSystem can change at runtime**
    public FixedLengthReport fixedLengthReport(String sourceSystem) {
         return new TdctFixedLengthReport(sourceSystem, dao);
    }
}

Aber ich erhalte den Fehler, dass sourceSystem nicht verdrahten konnte, weil keine Bohne gefunden wurde. Wie kann ich eine Bean mit Laufzeitkonstruktorargumenten erstellen?

Ich benutze Spring 4.2

23
suraj bahl

Sie können ein Prototyp-Bean zusammen mit einem BeanFactory verwenden.

@Configuration
public class AppConfig {

   @Autowired
   Dao dao;

   @Bean
   @Scope(value = "prototype")
   public FixedLengthReport fixedLengthReport(String sourceSystem) {
       return new TdctFixedLengthReport(sourceSystem, dao);
   }
}

@Scope(value = "prototype") bedeutet, dass Spring die Bean nicht direkt beim Start instanziiert, sondern später bei Bedarf. Um nun eine Instanz des Prototyp-Beans anzupassen, müssen Sie folgende Schritte ausführen.

@Controller
public class ExampleController{

   @Autowired
   private BeanFactory beanFactory;

   @RequestMapping("/")
   public String exampleMethod(){
      TdctFixedLengthReport report = 
         beanFactory.getBean(TdctFixedLengthReport.class, "sourceSystem");
   }
}

Hinweis: Da Ihre Bean beim Start nicht instanziiert werden kann, dürfen Sie Ihre Bean nicht direkt automatisch verdrahten. Andernfalls versucht Spring, die Bohne selbst zu instanziieren. Diese Verwendung verursacht einen Fehler.

@Controller
public class ExampleController{

   //next declaration will cause ERROR
   @Autowired
   private TdctFixedLengthReport report;

}
41
Ken Bekov

Ihr Code sieht gut aus. Um den Prototyp mit Parametern zu erhalten, verwenden Sie die BeanFactory # getBean (String name, Object ... args) -Methode.

Schauen Sie sich Spring Java Config: Wie erstellen Sie ein @Bean mit Prototyp-Gültigkeitsbereich und Laufzeitargumenten? BeanFactory # getBean (String name, Object ... args) würde sei was du suchst.

Ich vermute, dass Ihr IDEA (in meinem Fall IntelliJ IDEA Version 15)) den Fehler anzeigt und es ist kein Laufzeit-/Kompilierungsfehler

In IntelliJ können Sie die Einstellung für Federprüfungen ändern.

  • Gehen Sie zu Datei -> Einstellungen.
  • Geben Sie Inspektionen in das Suchfeld ein.
  • Gehen Sie zu Spring Core-> Code-> Autowire für Bean-Klassen.
  • Wechsel von "Fehler" zu "schwacher Warnung"
2
Haim Raman

Dies kann mit der Spring-Klasse ObjectProvider<> Erreicht werden, die in Spring 4.3 eingeführt wurde. Siehe Spring's Dokumentation für weitere Details.

Das Wesentliche ist, die Bean-Factory-Methode für das bereitzustellende Objekt zu definieren, den ObjectProvider<> In Ihren Consumer einzufügen und neue Instanzen des bereitzustellenden Objekts zu erstellen.

public class Pair
{
    private String left;
    private String right;

    public Pair(String left, String right)
    {
        this.left = left;
        this.right = right;
    }

    public String getLeft()
    {
        return left;
    }

    public String getRight()
    {
        return right;
    }
}

@Configuration
public class MyConfig
{
    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public Pair pair(String left, String right)
    {
        return new Pair(left, right);
    }
}

@Component
public class MyConsumer
{
    private ObjectProvider<Pair> pairProvider;

    @Autowired
    public MyConsumer(ObjectProvider<Pair> pairProvider)
    {
        this.pairProvider = pairProvider;
    }

    public void doSomethingWithPairs()
    {
        Pair pairOne = pairProvider.getObject("a", "b");
        Pair pairTwo = pairProvider.getObject("z", "x");
    }
}

HINWEIS: Sie implementieren die Schnittstelle ObjectProvider<> Nicht. Spring erledigt das für Sie automatisch. Sie müssen nur die Bean-Factory-Methode definieren.

0
HairOfTheDog