3

Ich spiele mit Spring Boot und ich versuche eine Instanz von ServiceImpl zu erstellen, die aufgelöst werden soll, wenn eine Service erforderlich ist. Zur Zeit notiere ich die Implementierung als @Component, aber das gibt mir nicht die Möglichkeit, die Instanz so zu konstruieren, wie ich will.Eine Instanz als 'Singleton'-Bean beim Start der Anwendung registrieren

Die ServiceImpl sollte mit einem String erstellt werden, der einen Pfad zu einer Datei auf der Festplatte enthält. Ich möchte dies in der Hauptmethode der @SpringBootApplication Klasse der Anwendung tun.

Vielleicht ist es komme ich gerade von einem Hintergrund langen .NET, wo wir die IoC-Container in der Regel Setup wie:

Service service = new Service("C:\\data.bin"); 
container.RegisterSingleton<IService>(service); // now whoever asks for a IService will receive this precise instance 

im Frühjahr Welt das Sinn machen?

LE: Ich bin mir der GoF-Singleton-Definition bewusst (d. H. Verhindern, dass alle anderen Instanzen der Klasse erstellen) - ich ziele nicht darauf ab.

+1

tun Sie diese Eigenschaft im Voraus wissen? Wenn ja, warum nicht in Eigenschaften speichern und direkt an die Bohne senden? – dimitrisli

+0

Ich habe nicht daran gedacht, es in den Eigenschaften zu speichern, das ist ein guter Vorschlag! In der Tat könnten Sie dies zu einer Antwort fördern :) –

Antwort

2

Wie im Kommentar beschrieben, können Sie dies tun, indem Sie Ihre Standortdetails in einer Konfigurationsdatei speichern und sie dann bei der Spring Bean-Initialisierung einlesen.

Angenommen, Ihre application.properties wie folgt aussieht:

my.sample.config.A=somelocationA 
my.sample.config.B=somelocationB 
my.sample.config.C=somelocationC 
my.sample.config.D.one=somelocationD1 
my.sample.config.D.two=somelocationD2 

Below ich Demo-ing 4 Möglichkeiten, dies zu tun zu erreichen:

.Durch Ihre Immobilie direkt an der Bean-Methode Schaffung Injizieren :

@Bean 
public A myBeanA(@Value("${my.sample.config.A}") String myprop) { 
    System.out.println("from bean A with " + myprop); 
    return new A(myprop); 
} 

.Durch Injizieren der prop erty auf einer Config weite Variable und verwenden, die in Ihrer Bean-Methode Schöpfung:

@Value("${my.sample.config.B}") 
private String mylocationB; 
//.. 
@Bean 
public B myBeanB() { 
    System.out.println("from bean B with " + mylocationB); 
    return new B(mylocationB); 
} 

.Durch die gesamte Umgebung in der Config-Injektion und dann die Eigenschaft von Hand pflücken benötigt:

@Autowired 
private Environment env; 
//.. 
    @Bean 
    public C myBeanC() { 
    String locationC = env.getProperty("my.sample.config.C"); 
    System.out.println("from bean C with " + locationC); 
    return new C(locationC); 
} 

. Dies ist eine Spring Boot exklusiven Weg. Sie können Type-safe Configuration Properties verwenden, indem Sie mit @ConfigurationProperties direkt annotieren, dass Ihr Bean einen Präfix-Namespace definiert und alle Parameter ab diesem Punkt automatisch den in dieser Bean definierten Eigenschaften zugeordnet werden!

@ConfigurationProperties(prefix = "my.sample.config.D") 
@Component 
class D { 
    private String one; 
    private String two; 

    public String getOne() { return one; } 

    public void setOne(String one) { 
     System.out.println("from bean D with " + one); 
     this.one = one; 
    } 
    public String getTwo() { return two; } 

    public void setTwo(String two) { 
     System.out.println("from bean D with " + two); 
     this.two = two; 
    } 
} 

Unterhalb der Gesamt one-Datei Code in einem Stück:

package com.example; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.boot.context.properties.ConfigurationProperties; 
import org.springframework.context.annotation.Bean; 
import org.springframework.core.env.Environment; 
import org.springframework.stereotype.Component; 

@SpringBootApplication 
public class DemoApplication { 

    @Autowired 
    private Environment env; 

    @Value("${my.sample.config.B}") 
    private String mylocationB; 

    @Bean 
    public A myBeanA(@Value("${my.sample.config.A}") String myprop) { 
     System.out.println("from bean A with " + myprop); 
     return new A(myprop); 
    } 

    @Bean 
    public B myBeanB() { 
     System.out.println("from bean B with " + mylocationB); 
     return new B(mylocationB); 
    } 

    @Bean 
    public C myBeanC() { 
     String locationC = env.getProperty("my.sample.config.C"); 
     System.out.println("from bean C with " + locationC); 
     return new C(locationC); 
    } 

    @ConfigurationProperties(prefix = "my.sample.config.D") 
    @Component 
    class D { 
     private String one; 
     private String two; 

     public String getOne() { return one; } 

     public void setOne(String one) { 
      System.out.println("from bean D with " + one); 
      this.one = one; 
     } 
     public String getTwo() { return two; } 

     public void setTwo(String two) { 
      System.out.println("from bean D with " + two); 
      this.two = two; 
     } 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 

    class A { 
     private final String location; 
     public A(String location) { this.location = location; } 
    } 

    class B { 
     private final String location; 
     public B(String location) { this.location = location; } 
    } 

    class C { 
     private final String location; 
     public C(String location) { this.location = location; } 
    } 

} 
+0

Danke, nette Antwort. Es wird besser sein, wenn Sie erklären, wie man Klasse D verwendet. –

+0

@EmdadulSawon Danke - Ich habe einen Link zur Dokumentation hinzugefügt, wo Sie alle Details darüber finden. – dimitrisli

1

In der gleichen Datei, die Sie @SpringBootApplication tun haben:

@Bean 
public IService service() { 
    return new Service("C:\\data.bin"); 
} 

Frühling alles für dich autowire sollte. Es sollte standardmäßig ein Singleton sein (http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes).

Edit 1: Sie sollten auch Ihre Service-Implementierung mit @Service anstelle von @Component beschriften (siehe: What's the difference between @Component, @Repository & @Service annotations in Spring?).

Edit 2: Sie müssen auch nicht unbedingt die @Bean Methode in die Klasse, die @SpringBootApplication hat. Sie können es in jede Klasse mit der @Configuration Annotation einfügen.

+0

endete mit dieser Version :) –

Verwandte Themen