我们可以将没有默认构造函数的Service bean注入到控制器中吗?
我有以下控制器
@Controller
public class ArticleController {
@Autowired
private WithConstructorService withConstructorService;
...
}
我的服务是:
@Service
public class WithConstructorServiceImpl implements WithConstructorService {
String name;
String address;
public WithConstructorServiceImpl(String name, String address) {
super();
this.name = name;
this.address = address;
}
}
我得到了异常
SEVERE: Servlet /springheat threw load() exception
java.lang.NoSuchMethodException: WithConstructorServiceImpl.<init>()
更新:
我在这里做了一个猜测,但是我们可以做一些AOP魔术,仍然使用带注释的构造函数arg服务方法吗?
如果您使用spring 3,您可以使用@Value
注释来连接名称和地址字段,然后它们不需要通过构造函数设置。或者,不要使用@Service
注释,而是用适当的<constructor-arg>
标记在xml中声明bean。
无论哪种方式,spring容器都需要知道从哪里获得名称和地址的值,否则它不能构造您的WithConstructorServiceImpl。
您可以这样做,但是由于Spring必须实例化bean,因此您必须告诉他将哪些值传递给构造函数。
第一种可能:自动连接两个参数:
@Autowired
public WithConstructorServiceImpl(@Qualifier("theNameBean") String name,
@Qualifier("theAdressBean") String address) {
在这种情况下,您必须在context.xml文件中声明两个String类型的bean,并使用适当的名称。
第二种可能:在context.xml文件中声明bean本身,并告诉Spring它必须向构造函数传递哪些参数。
看到http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html beans-factory-collaborators
不行。因为当bean被注入时,它使用默认构造函数创建bean本身,并且只有在它的所有属性都被注入之后。
您所能做的就是为name和address创建setter,然后将它们添加到注入的bean中。