【问题标题】:Spring annotated controller bean duplicate in application context应用程序上下文中的 Spring 注释控制器 bean 重复
【发布时间】:2011-11-21 09:50:33
【问题描述】:

当我在我的应用上下文中定义波纹管控制器时,我在尝试使用它时遇到重复错误。

如何将构造函数参数传递给控制器​​而不收到重复的错误消息?

我的应用程序上下文:

 <context:component-scan base-package="org.brickred.socialauth.spring.controller" />

 <bean id="socialAuthWebController" class="org.brickred.socialauth.spring.controller.SocialAuthWebController">
    <constructor-arg value="http://www.mysite.com/" />
    <constructor-arg value="/authSuccess.html" />
    <constructor-arg value="/failed.html" />
 </bean>

 <tx:annotation-driven transaction-manager="txManager"/>

带注释的控制器:

    @Controller
    @RequestMapping("/socialauth")
    public class SocialAuthWebController {

    private String baseCallbackUrl;
    private String successPageURL;
    private String accessDeniedPageURL;
    @Autowired
    private SocialAuthTemplate socialAuthTemplate;
    @Autowired
    private SocialAuthManager socialAuthManager;
    private final Log LOG = LogFactory.getLog(getClass());

    /**
     * Constructs a SocialAuthWebController.
     * 
     * @param applicationUrl
     *            the base URL for this application (with context e.g
     *            http://opensource.brickred.com/socialauthdemo, used to
     *            construct the callback URL passed to the providers
     * @param successPageURL
     *            the URL of success page or controller, where you want to
     *            access sign in user details like profile, contacts etc.
     * @param accessDeniedPageURL
     *            the URL of page where you want to redirect when user denied
     *            the permission.
     */
    @Inject
    public SocialAuthWebController(final String applicationUrl,
                    final String successPageURL, final String accessDeniedPageURL) {
            this.baseCallbackUrl = applicationUrl;
            this.successPageURL = successPageURL;
            this.accessDeniedPageURL = accessDeniedPageURL;
    }
    ...

其余的源代码在 http://code.google.com/p/socialauth/source/browse/trunk/socialauth-spring/src/org/brickred/socialauth/spring/controller/SocialAuthWebController.java

我收到以下错误:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'socialAuthWebController' defined in URL [jar:file://Tomcat%207.0/webapps/ROOT/WEB-INF/lib/socialauth-spring-2.0-beta2.jar!/org/brickred/socialauth/spring/controller/SocialAuthWebController.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [java.lang.String]: : No matching bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [java.lang.String] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}

【问题讨论】:

标签: java spring constructor controller annotations


【解决方案1】:

您收到错误是因为在 XML 和注释中都定义了相同的控制器,正如其他帖子所指出的那样。删除控制器的 XML 配置并执行以下操作:

由于成功和失败 URL 不是真正的配置值,而是在您的应用程序中定义,因此将它们 1) 直接作为硬编码值移动到处理程序方法中,或者 2) 如果它们对多个方法通用或控制器,将它们作为常量移动到所有其他控制器扩展的 BaseController 中。然后你就完全避免了这两个论点的 DI 问题。

剩下的是baseCallbackUrl。如果这是一个依赖于应用程序 URL 的值,则可以将该值设为系统变量并使用 @Value 直接注入它,如下所示:

@Value("#{systemProperties.baseCallbackUrl}")
private String baseCallbackUrl;

【讨论】:

    【解决方案2】:

    我认为组件扫描正在加载控制器,并且您的 bean 再次加载,因为它是在 xml (bean id="socialAuthWebController") 中定义的。

    您可以尝试评论组件扫描或 bean 声明吗? &lt;context:component-scan base-package="org.brickred.socialauth.spring.controller" /&gt;

    【讨论】:

    • 我猜这可以通过&lt;mvc:annotation-driven /&gt; 工作(我在你的sn-p 中没有看到),component-scan 不是特定于mvc 的(并且用于加载所有类型的spring beans)。
    • @MatBanik tx 与 mvc/组件扫描无关。基本上你应该寻找的是为什么 bean 被加载两次,这可以是 xml 文件中的显式 bean 声明或组件扫描。
    • @MatBanik static.springsource.org/spring/docs/3.0.x/… 我认为拥有与否不会影响当前的问题。
    【解决方案3】:

    也许尝试声明值的名称。见Spring Documentation

    <constructor-arg name="applicationUrl" value="http://www.mysite.com/" /> 
    

    我认为 Spring 可能有问题,因为它不知道哪个 String 去哪里。所以你可以使用“名称”或“索引”来让它知道。

    来自链接:“如果 bean 定义的构造函数参数中不存在潜在的歧义,那么在 bean 定义中定义构造函数参数的顺序就是将这些参数提供给适当的构造函数时的顺序bean 正在被实例化”

    由于您使用的是所有字符串,因此存在歧义。

    【讨论】:

    • 你也尝试过使用索引吗?
    • 我重新阅读了文档。看起来您需要使用索引或类型。
    • "使用简单类型时,如true,Spring无法判断该值的类型,因此无法在没有帮助的情况下按类型匹配"
    • "如果您使用 type 属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配"
    • "使用 index 属性明确指定构造函数参数的索引"
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多