Suppose the bean is registered here.
@Configuration
public class configuration{
@Bean(name = "MyClass")
public MyClass getMyClass(@Value("avalue") final String s){
return new MyClass(s);
}
}
}
And the class has another class instantiated inside as below (No annotation needed for either?)
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;
}
}
How this mechanic works? Is it safe to instantiate a new instance within a bean injection? What's the advantage or disadvantage of doing so?
If we were to avoid using it by making MyOtherClass a bean too, would this be the way? (Mainly concerning: is @Autowired and getMyclass() taking the right place or it's redundant?)
@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;
}
}
If you want not to expose your
MyOtherClassand take control over creating its instances, you can use your first approach:It is safe, but it is not a dependency injection:
MyOtherClassis not managed by Spring, so you won't be able to inject it in other beans using@Autowiredor to inject other spring managed classes intoMyOtherClass. Also, as mentioned by Andrew, it becomes impossible to mockMyOtherClass.If registering
MyOtherClassas a bean in a Spring context is fine, then the easiest way is to annotate both classes with@Componentand let Spring do its work (in this case you should use@ComponentScanto help Spring auto-detect your classes):Or, using
@Bean(this will work ifConfig.javaandMyClass.javaare in different projects):Note: if you have already registered
MyClassin a Spring context usingthen you don't need to do it again by