0

I just start learning spring. I read some codes like below. But I don't understand how ResultBuilderFactory can return the correct class. Can somebody please explain? Thanks!

public interface ResultBuilder{
  public void print();
}
@Component
public class DefaultResultBuilder implement ResultBuilder{
  public void print(){System.out.printlin("DefaultResultBuilder"};
}
@Component
public class HtmlResultBuilder implement ResultBuilder{
  public void print(){System.out.printlin("HtmlResultBuilder"};
}
@Component
public class ResultBuilderFactory{
 private final ResultBuilder defaultResultBuilder;
 private final ResultBuilder htmlResultBuilder;

public ResultBuilder get(String name){
  if(name.equal("HTML") return htmlResultBuilder;
  return defaultResultBuilder;
}

Updated:

Just update typo for Component annotation. My bad... I tried the code, and got error: "ResultBuilderFactory required a single bean, but 2 were found....Consider marking one of the beans as @Primary, ... or using @Qualifer..." How can the original code work without using Primary or @Qualifier

Abe
  • 310
  • 3
  • 15
yulinxp
  • 11
  • 2
  • The code shown has nothing to do with Spring except the misspelled component annotation. This is called [Factory Pattern](https://www.tutorialspoint.com/design_pattern/factory_pattern.htm) – Abhijit Sarkar Feb 26 '22 at 03:32
  • I used Sanjay Bharwani's solution https://stackoverflow.com/questions/6390810/implement-a-simple-factory-pattern-with-spring-3-annotations – Abe Aug 24 '22 at 16:40

1 Answers1

0

Spring will create bean defaultResultBuilder and htmlResultBuilder. You will need to inject them to ResultBuilderFactory.

Lombok annotation @RequiredArgsConstructor does the constructor injection.

@Component
@RequiredArgsConstructor
public class ResultBuilderFactory{
    private final ResultBuilder defaultResultBuilder;
    private final ResultBuilder htmlResultBuilder;
}

Or you can use field injection. But they can't be final fields.

@Component
public class ResultBuilderFactory{

    @Autowired
    private  ResultBuilder defaultResultBuilder;

    @Autowired
    private  ResultBuilder htmlResultBuilder;
}

But you should choose construtor inject if possible. See discussion Spring @Autowire on Properties vs Constructor

Abe
  • 310
  • 3
  • 15