Je veux créer un bean Spring dans Spring Java avec quelques arguments de constructeur passés à l'exécution. J'ai créé ce qui suit Java config, dans laquelle il existe un bean fixedLengthReport qui attend certains arguments dans le constructeur.
@Configuration
public class AppConfig {
@Autowrire
Dao dao;
@Bean
@Scope(value = "prototype")
**//SourceSystem can change at runtime**
public FixedLengthReport fixedLengthReport(String sourceSystem) {
return new TdctFixedLengthReport(sourceSystem, dao);
}
}
Mais je reçois une erreur que sourceSystem n'a pas pu câbler car aucun bean n'a été trouvé. Comment puis-je créer un bean avec des arguments de constructeur d'exécution?
J'utilise Spring 4.2
Vous pouvez utiliser un bean prototype avec un BeanFactory
.
@Configuration
public class AppConfig {
@Autowired
Dao dao;
@Bean
@Scope(value = "prototype")
public FixedLengthReport fixedLengthReport(String sourceSystem) {
return new TdctFixedLengthReport(sourceSystem, dao);
}
}
@Scope(value = "prototype")
signifie que Spring n'instanciera pas le bean dès le démarrage, mais le fera plus tard à la demande. Maintenant, pour personnaliser une instance du bean prototype, vous devez procéder comme suit.
@Controller
public class ExampleController{
@Autowired
private BeanFactory beanFactory;
@RequestMapping("/")
public String exampleMethod(){
TdctFixedLengthReport report =
beanFactory.getBean(TdctFixedLengthReport.class, "sourceSystem");
}
}
Notez que, comme votre bean ne peut pas être instancié au démarrage, vous ne devez pas câbler automatiquement votre bean; sinon Spring essaiera d'instancier le haricot lui-même. Cette utilisation entraînera une erreur.
@Controller
public class ExampleController{
//next declaration will cause ERROR
@Autowired
private TdctFixedLengthReport report;
}
Votre code semble correct, pour obtenir le prototype avec des paramètres, utilisez la méthode BeanFactory # getBean (String name, Object ... args).
Regardez Spring Java Config: comment créer un @Bean de portée prototype avec des arguments d'exécution? BeanFactory # getBean (String name, Object ... args) serait soyez ce que vous cherchez.
Je suppose que votre IDEA (dans mon cas IntelliJ IDEA version 15.) vous donne l'erreur et ce n'est pas un erreur d'exécution/de compilation.
Dans IntelliJ, vous pouvez modifier le réglage des inspections de printemps.
Ceci peut être réalisé avec le ObjectProvider<>
classe introduite au printemps 4.3. Voir Spring's documentation pour plus de détails.
L'essentiel est de définir la méthode de fabrique de bean pour l'objet à fournir, injecter le ObjectProvider<>
dans votre consommateur et créez de nouvelles instances de l'objet à fournir.
public class Pair
{
private String left;
private String right;
public Pair(String left, String right)
{
this.left = left;
this.right = right;
}
public String getLeft()
{
return left;
}
public String getRight()
{
return right;
}
}
@Configuration
public class MyConfig
{
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Pair pair(String left, String right)
{
return new Pair(left, right);
}
}
@Component
public class MyConsumer
{
private ObjectProvider<Pair> pairProvider;
@Autowired
public MyConsumer(ObjectProvider<Pair> pairProvider)
{
this.pairProvider = pairProvider;
}
public void doSomethingWithPairs()
{
Pair pairOne = pairProvider.getObject("a", "b");
Pair pairTwo = pairProvider.getObject("z", "x");
}
}
REMARQUE: vous n'implémentez pas réellement le ObjectProvider<>
interface; Spring fait cela pour vous de façon automatique. Il vous suffit de définir la méthode de fabrique de bean.