2

考虑以下(检票口)代码:

@SpringBean(required=false)
private StatusCheckService service;

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

然而:

@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,但我将其标记为可选,为什么会出现异常?有没有办法解决?

4

1 回答 1

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();

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

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

祝你好运!

于 2012-07-18T09:40:28.827 回答