Reputation: 21
I have a bean in xml:
<bean id="fooBean" class="org.model.Foo" scope="prototype">
<property name="propOne" ref="fooBarOne"/>
<property name="propTwo" ref="fooBarTwo"/>
<property name="propThree" ref="fooBarThree"/>
</bean>
I converted it in java like this:
@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Foo fooBean(
FooBarOneImpl fooBarOne,
FooBarTwoImpl fooBarTwo,
FooBarThreeImpl fooBarThree
) {
Foo foo = new Foo();
foo.setPropOne(fooBarOne);
foo.setPropTwo(fooBarTwo);
foo.setPropThree(fooBarThree);
return foo;
}
When I execute:
(IFoo) applicationContext.getBean("fooBean", pizza, patatine, cocaCola);
with the xml config it works correctly, with Java config it gives I get an Exception.
The exception is the following:
org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.model.Foo]: Illegal arguments to factory method 'fooBean'; args: "ciao","11","abc"; nested exception is java.lang.IllegalArgumentException: argument type mismatch
The class Foo has the constructor defined Foo(String pizza, String patatine, String cocaCola){...}.
Why when the bean is defined in the xml it finds the right constructor?
I tried to change the java conversion
Upvotes: 0
Views: 59
Reputation: 1092
@Bean
public FooBarOne propOne() { // Bean name will be set by method name
return new FooBarOne(); // if FooBarOne is an interface, use here any implementation
}
@Bean
public FooBarTwo propTwo() { // Bean name will be set by method name
return new FooBarTwo(); // if FooBarTwo is an interface, use here any implementation
}
@Bean
public FooBarThree propThree() { // Bean name will be set by method name
return new FooBarThree(); // if FooBarThree is an interface, use here any implementation
}
@Bean
@Scope("prototype")
public Foo fooBean(FooBarOne a, FooBarTwo b, FooBarThree c) {
// Here, I linked by type name and not bean name. The name of the parameter is optional, it can be anything you like.
// If you want to link by bean name, use @Qualified annotation.
// This annotation is needed if the bean injection is not trivial.
return new Foo(a, b, c)
}
Another critical topic: If you defined a CLASS return type, we can't be referencing the instance's interface.
interface I {}
class A implemented I {}
// ------------------------------------------------------
@Bean
public A a() { return new A() }
@Bean
public A a(I instance) { ... } // ERROR
@Bean
public A a(A instance) { ... } // OK
// ------------------------------------------------------
@Bean
public I a() { return new A() }
@Bean
public A a(I instance) { ... } // OK
@Bean
public A a(A instance) { ... } // ERROR
If you use @Service/@Repository/@Component on your class, you can do ref because Spring will scan your project. Spring won't do it via @Bean because @Bean is the direct definition.
Upvotes: 0