Reputation: 5867
Can we inject a Service bean with no default constructor into a controller?
I have the following controller
@Controller
public class ArticleController {
@Autowired
private WithConstructorService withConstructorService;
...
}
And my service is:
@Service
public class WithConstructorServiceImpl implements WithConstructorService {
String name;
String address;
public WithConstructorServiceImpl(String name, String address) {
super();
this.name = name;
this.address = address;
}
}
I'm getting the exception
SEVERE: Servlet /springheat threw load() exception
java.lang.NoSuchMethodException: WithConstructorServiceImpl.<init>()
update:
I'm making a guess here but can we do some AOP magic and still use annotated constructor arg service method?
Upvotes: 4
Views: 3771
Reputation: 691973
You can do that, but since Spring must instantiate the bean, you must tell him which values to pass to the constructor.
First possibility: autowire the two arguments:
@Autowired
public WithConstructorServiceImpl(@Qualifier("theNameBean") String name,
@Qualifier("theAdressBean") String address) {
In this case, you'll have to declare two beans of type String in the context.xml file, with the appropriate name.
Second possibility: declare the bean itself in the context.xml file and tell Spring which arguments it must pass to the constructor.
Upvotes: 2
Reputation: 25269
If you're using spring 3 you can use the @Value
annotation to wire the name and address fields, and then they don't need to be set thru the constructor. Or, don't use the @Service
annotation and instead declare your bean in xml with appropriate <constructor-arg>
tags.
Either way, the spring container needs to know where to get the values for name and address, or it can't construct your WithConstructorServiceImpl.
Upvotes: 2
Reputation: 18639
No, you can't. Because when the bean is injected it creates the bean itself using the default constructor and only after it all its properties are injected.
What you can do is just to create setters for name and address and then add it to the injected bean.
Upvotes: 0