3

Я играю с Spring Boot, и я пытаюсь построить экземпляр ServiceImpl, который нужно решить, когда требуется Service. В настоящее время я комментирую реализацию как @Component, но это не дает мне возможности построить экземпляр так, как я хочу.Регистрация экземпляра как компонента «singleton» при запуске приложения

ServiceImpl должен быть построен с помощью строки, содержащей путь к файлу на диске. Я хотел бы сделать это в основном методе класса @SpringBootApplication приложения.

Может быть, это только мне приходит из длинного фона .NET, где мы обычно настроить IoC контейнер как:

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

это имеет смысл в Спринг мире?

LE: Я хорошо знаю определение Singleton GoF (т. Е. Препятствует тому, чтобы все остальные создавали экземпляры класса). Я не нацеливаюсь на это.

+1

вы знаете, это свойство заранее? Если да, то почему бы не сохранить его в свойствах и autowire он прямо к bean-компоненту? – dimitrisli

+0

Я не думал хранить его в свойствах, это хорошее предложение! На самом деле вы могли бы продвигать это до ответа :) –

ответ

2

Как описано в комментарии, это можно сделать, сохранив данные о местоположении в файле конфигурации, а затем введи их при инициализации Spring Bean.

Предполагая, что ваш application.properties выглядит следующим образом:

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 

Ниже я демо-ки 4 способа сделать достижения этой цели:

.При инъекционные свою собственность непосредственно на создание метода Bean :

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

.При инъекционного пропеллер erty на Config шириной переменной и использовать его в своем создании метода Bean:

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

.При инъекционного всю окружающую среду в Config, а затем вручную выбрать свойство, необходимое:

@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); 
} 

. Это эксклюзивный способ пружинной загрузки. Вы можете использовать Type-safe Configuration Properties, аннотируя @ConfigurationProperties непосредственно вашим компонентом, определяющим пространство имен префиксов, и все параметры с этого момента будут автоматически отображены в свойствах, определенных в этом компоненте!

@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; 
    } 
} 

Ниже общего кода один-файла в одной части:

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

Спасибо, хороший ответ. Будет лучше, если вы объясните, как использовать класс D. –

+0

@ EmdadulSawon Спасибо - я добавил ссылку на документацию, где вы найдете все подробности об этом. – dimitrisli

1

В том же файле, что у вас есть @SpringBootApplication сделать:

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

Весна должна autowire все для вас. По умолчанию он должен быть одиночным (http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes).

Редактировать 1: Вы должны также аннотировать вашу реализацию службы с помощью @Service вместо @Component (см.: What's the difference between @Component, @Repository & @Service annotations in Spring?).

Редактировать 2: Вам также необязательно ставить метод @Bean в классе, который имеет @SpringBootApplication. Вы можете поместить его в любой класс с аннотацией @Configuration.

+0

закончил с использованием этой версии :) –