我正在使用Spring Boot,我正在尝试构建一个ServiceImpl
的实例,以便在需要Service
时解析。目前我正在将实现注释为@Component
,但这并没有让我有机会按我的意愿构建实例。
ServiceImpl
应该使用包含磁盘上文件路径的String构造。我想在应用程序的@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
这在Spring世界中有意义吗?
LE:我很清楚GoF单例定义(即阻止其他人创建该类的实例) - 我不是以此为目标。
答案 0 :(得分:5)
在您@SpringBootApplication
执行的同一文件中:
@Bean
public IService service() {
return new Service("C:\\data.bin");
}
Spring应该为你自动装配所有东西。默认情况下它应该是单身(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
注释的类中。
答案 1 :(得分:4)
如评论中所述,这可以通过将您的位置详细信息存储在配置文件中,然后在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种实现此目的的方法:
1 。直接在Bean方法创建上注入您的属性:
@Bean
public A myBeanA(@Value("${my.sample.config.A}") String myprop) {
System.out.println("from bean A with " + myprop);
return new A(myprop);
}
2 。通过在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);
}
3 。通过在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);
}
4 。这是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; }
}
}