假设bean在这里注册。
@Configuration
public class configuration{
@Bean(name = "MyClass")
public MyClass getMyClass(@Value("avalue") final String s){
return new MyClass(s);
}
}
}
并且该类在内部实例化了另一个类,如下所示(两者都不需要注释?)
public class MyClass{
MyOtherClass myOtherClass;
public MyClass(String s){
this.myOtherClass = new MyOtherClass(s);
}
}
public class MyOtherClass{
String s;
public MyOtherClass(String s){
this.s = s;
}
}
这种机制如何运作?在bean注入中实例化一个新实例是否安全?这样做有什么好处或缺点?
如果我们通过将MyOtherClass变成bean来避免使用它,那会是这样吗? (主要是关于:@Autowired和getMyclass()是否占据了正确的位置,或者它是多余的?)
@Configuration
public class configuration{
@Bean(name = "MyOtherClass")
public MyOtherClass getMyOtherClass(@Value("avalue") final String s){
return new MyOtherClass(s);
}
}
@Bean(name = "MyClass")
public MyClass getMyClass(MyClass myClass){
//I was told the input should be myClass not myOtherClass,
//and the return is myClass not new MyClass(myOtherClass);
//since it's already autowired. Is that correct?
//What if the configuration.java and MyClass.java are in different project?
return myClass;
}
}
}
@Component
public class MyClass{
MyOtherClass myOtherClass;
@Autowired
public MyClass(MyOtherClass myOtherClass){
this.myOtherClass = myOtherClass;
}
}
public class MyOtherClass{
String s;
public MyOtherClass(String s){
this.s = s;
}
}
答案 0 :(得分:1)
在bean注入中实例化一个新实例是否安全?
是。但是,新实例不是由Spring管理的。 (对不起,如果那是显而易见的。)
但也许更重要的是与Spring无关,这样做:
public class MyClass{
MyOtherClass myOtherClass;
public MyClass(String s){
this.myOtherClass = new MyOtherClass(s);
}
}
很难进行单元测试,因为没有简单的方法来模拟myOtherClass
。
与Spring无关,重构使用IoC以便于单元测试:
public class MyClass{
private final MyOtherClass myOtherClass;
public MyClass(MyOtherClass myOtherClass){
this.myOtherClass = myOtherClass;
}
}
将类配置为Spring bean,但没有MyOtherClass
也作为bean:
@Configuration
public class Configuration{
private MyOtherClass getMyOtherClass(final String s){
return new MyOtherClass(s);
}
}
@Bean(name = "MyClass")
public MyClass getMyClass(@Value("avalue") final String s){
return new MyClass(getMyOtherClass(s));
}
}
}
你发布的关于@Component和@Autowire的内容可行,但听起来你想避免将MyOtherClass
暴露为bean。
答案 1 :(得分:1)
如果您不想公开MyOtherClass
并控制其创建实例,可以使用第一种方法:
...
public MyClass(String s) {
this.myOtherClass = new MyOtherClass(s);
}
它是安全的,但它不是依赖注入:MyOtherClass
不是由Spring管理的,所以你将无法使用@Autowired
将其注入其他bean或注入其他spring托管类到MyOtherClass
。另外,正如安德鲁所提到的,模仿MyOtherClass
变得不可能。
如果在Spring上下文中将MyOtherClass
注册为bean是正常的,那么最简单的方法是使用@Component
注释两个类并让Spring完成其工作(在这种情况下,您应该使用{{ 1}}帮助Spring自动检测你的类):
@ComponentScan
或者,使用@Component
class MyClass {
MyOtherClass myOtherClass;
@Autowired
public MyClass(MyOtherClass myOtherClass){
this.myOtherClass = myOtherClass;
}
}
@Component
class MyOtherClass {
String s;
public MyOtherClass(@Value("avalue") final String s){
this.s = s;
}
}
(如果@Bean
和Config.java
位于不同的项目中,这将有效):
MyClass.java
注意:如果您已使用
在Spring上下文中注册了@Configuration
public class Config {
@Value("avalue")
private String s;
@Bean(name = "myClass")
public MyClass getMyClass(){
return new MyClass(getMyOtherClass());
}
@Bean(name = "myOtherClass")
public MyOtherClass getMyOtherClass() {
return new MyOtherClass(s);
}
}
MyClass
然后你不需要再通过
再做一次@Component
public class MyClass {
...
}