Spring-Wicket:仍然需要可选但命名的bean

时间:2012-06-26 16:22:20

标签: spring dependency-injection wicket wicket-1.5

考虑以下(wicket)代码:

@SpringBean(required=false)
private StatusCheckService service;

在我的用例中,我的上下文中没有StatusCheckService类型的bean。 这不是问题,它被标记为可选,因此(wicket)页面将初始化正常。

然而:

@SpringBean(name = "statusCheckService", required=false)
private StatusCheckService service;

这失败了:

org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'statusCheckService' is defined
     at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:529)
     at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1095)
     at org.springframework.beans.factory.support.AbstractBeanFactory.isSingleton(AbstractBeanFactory.java:400)
     at org.springframework.context.support.AbstractApplicationContext.isSingleton(AbstractApplicationContext.java:1113)
     at org.apache.wicket.spring.SpringBeanLocator.isSingletonBean(SpringBeanLocator.java:100)
     at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:140)

我希望它没有任何区别。好的,没有带有这样名字的bean,但是我把它标记为可选,那为什么会有例外?有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

通过在eclipse中进行使用搜索,您可以看到在AnnotProxyFieldValue的第215行上唯一一次查询注释的所需值:

if (names.isEmpty())
{
    if (annot.required())
    {
        throw new IllegalStateException("bean of type [" + clazz.getName() + "] not found");
    }
    return null;
}

在这里你可以看到@SpringBean注释的'required'字段仅在名字列表(在函数中设置得更高)为空时使用...

这解释了您遇到的行为,因为当您未指定名称时,名称列表为空(因为它找不到您的类),并返回null。但是,如果你确实指定了一个名称,它就不会试图查看该类是否存在,因此发送你提供的spring类名来查找,当它找不到类时会继续抱怨。

这可能是一个错误,取决于设计师的意图,我个人认为,如果你已经指定不需要该字段,那么该功能应该提前返回...如果你同意那么可以考虑快速启动jira机票

至于解决方案,你没有提到很多关于你的用例,以及为什么你需要设置名称,即使你不需要注入bean。但假设您正在根据某些条件动态注入bean,您可以执行以下操作:(未经测试)

在注入SpringBean的类中,替换:

@SpringBean(name="statusCheckService", required=false)
private StatusCheckService service;

使用:

MyCustomSpringBeanInjector injectedService;

然后MyCustomSpringBeanInjector类就像:

import org.apache.wicket.injection.Injector;
import org.apache.wicket.spring.injection.annot.SpringBean;

public class MyCustomSpringBeanInjector
{
    @SpringBean public StatusCheckService service;

    public MyCustomSpringBeanInjector()
    {
        Injector.get().inject(this);
    }
}

然后回到注入SpringBean的类中,添加如下内容:

if(statusCheckServiceRequired)
    injectedService = new MyCustomSpringBeanInjector();

并替换“服务”。必要时使用“injectService.service”。

显然,这是一个qwik-e修复我的头脑,我相信有更好的方法,但你明白了! :)

祝你好运!