Reputation: 14550
I want to be able to autowire a singleton bean (foo
)
@Component
public class FooUser {
@Autowire Foo foo;
}
created by another singleton's method (FooFactory.createFoo
)
@Service
public class FooFactory {
public Foo createFoo() {...}
}
with xml it's simply factory-method
. How can i do it with annotation?
Upvotes: 16
Views: 39898
Reputation: 344
Spring Boot: factory method
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
enum ParsersConst {
bofa, jpm, wellsforgo
}
interface Parser {
String readFromFile(String file);
}
class JPM implements Parser {
@Override
public String readFromFile(String file) {
System.out.println("From JPM Parser");
//LOGIC to read file data
return "JPM";
}
}
class Bofa implements Parser {
@Override
public String readFromFile(String file) {
System.out.println("From Bofa Parser");
//LOGIC to read file data
return "BOFA";
}
}
class WellsForgo implements Parser {
@Override
public String readFromFile(String file) {
System.out.println("From Wellsforgo Parser");
//LOGIC to read file data
return "WellsForgo";
}
}
class ParserCreator {
private Map<ParsersConst, Parser> parserMap;
public Parser createParser(ParsersConst parsConst) {
Parser parser = parserMap.get(parsConst);
if (parserMap.get(parsConst) != null) {
return parser;
}
throw new IllegalArgumentException("Unknown Parser");
}
public void setParserMap(Map<ParsersConst, Parser> parserMap) {
this.parserMap = parserMap;
}
}
@Configuration
class ParserConfig {
@Bean
public ParserCreator parserCreatorFactory() {
ParserCreator factory = new ParserCreator();
Map<ParsersConst, Parser> map = new HashMap<ParsersConst, Parser>();
map.put(ParsersConst.bofa, new Bofa());
map.put(ParsersConst.wellsforgo, new WellsForgo());
map.put(ParsersConst.jpm, new JPM());
factory.setParserMap(map);
return factory;
}
@Bean
public Parser bofa() {
return parserCreatorFactory().createParser(ParsersConst.bofa);
}
@Bean
public Parser wellsforgo() {
return parserCreatorFactory().createParser(ParsersConst.wellsforgo);
}
@Bean
public Parser jpm() {
return parserCreatorFactory().createParser(ParsersConst.jpm);
}
}
@Component
public class StaticFacotryDemo implements CommandLineRunner {
@Autowired
private ApplicationContext context;
@Override
public void run(String... args) throws Exception {
Parser parser = (Parser) context.getBean(ParsersConst.jpm.toString());
System.out.println(parser.readFromFile("jan_stmt.pdf"));
}
}
Upvotes: 0
Reputation: 14178
Spring Components can also define factory methods. A snipped from the documentation:
@Component
public class FactoryMethodComponent {
@Bean @Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
public void doWork() {
// Component method implementation omitted
}
}
Upvotes: 4
Reputation: 101
use the FactoryBean Spring interface. then u will be able to autowire T itself
EDIT: The BeanFactory is an interface in Spring where if you implement it You can make a factory of the object such as :
public class FooFactoryBean implements FactoryBean<Foo>{
..................
}
then you can initialize the bean :
@Bean
public FooFactoryBean foo(){
return new FooFactoryBean();
}
then if you autowired Foo it Spring will understand the FooFactoryBean is the desired factory
@Autowired
Foo foo;
Upvotes: 0
Reputation: 340743
Try Java @Configuration
instead:
@Configuration
public class Config {
@Bean
public FooUser fooUser() {
return new FooUser(foo());
}
@Bean
public FooFactory fooFactory() {
return new FooFactory();
}
@Bean
public Foo foo() {
return fooFactory().createFoo();
}
}
Upvotes: 16
Reputation: 597116
You need java-config - the @Bean
annotation.
Define your class as @Configuration
and your method as @Bean
Upvotes: 4