3

我正在玩Spring Boot,我试图构建一个ServiceImpl的实例,以便在需要Service时解决。目前我将注释的实现注释为@Component,但这并不能让我有机会根据需要构建实例。在应用程序启动时将实例注册为'singleton'bean

ServiceImpl应用含于磁盘上的文件的路径的字符串构成。我想在应用程序的@SpringBootApplication类的主要方法中执行此操作。

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

春季世界这是否有道理:

也许这只是我从一个长的.NET背景,我们通常设置类似IoC容器来了吗?

LE:我深知GoF的单定义(即防止其他人从创建类的实例) - 我不是针对这个。

+1

你事先知道这个属性?如果是的话,为什么不把它存储在属性中,并直接将它自动装入到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 

下面我演示-ING 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在配置范围内的变量和使用,在您的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); 
} 

。通过注入在配置整个环境,然后手动选择所需的属性:

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

。这是Spring Boot的独家方式。您可以使用Type-safe Configuration Properties直接使用@ConfigurationProperties注释您的bean定义前缀名称空间,并且从该点开始的所有参数将自动映射到该bean中定义的属性!

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

春季应自动装配了一切为您服务。它应该是默认的单身人士(http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes)。

编辑1:你还应该用@服务,而不是@Component(:What's the difference between @Component, @Repository & @Service annotations in Spring?见)注释服务实现。

编辑2:您也不一定必须将@Bean方法放在@SpringBootApplication的类中。您可以将它放在任何具有@Configuration注释的课程中。在注释中描述

+0

结束了使用此版本:) –

相关问题