在控制器中注入没有默认构造函数的bean



我们可以将没有默认构造函数的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中。

相关内容

最新更新