开发者

Spring annotated controller bean duplicate in application context

开发者 https://www.devze.com 2023-04-06 01:09 出处:网络
When I define bellow controller in my app context I\'m getting duplicate errors when I try to use it.

When I define bellow controller in my app context I'm getting duplicate errors when I try to use it.

How do I pass the constructor-args to the controller without getting duplicate error messages?

My application context:

 <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"/>

The annotated controller:

    @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
     * @par开发者_C百科am 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;
    }
    ...

rest of the source code at http://code.google.com/p/socialauth/source/browse/trunk/socialauth-spring/src/org/brickred/socialauth/spring/controller/SocialAuthWebController.java

I get following error:

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: {}


You're getting the error because the same Controller is defined in both XML and annotations, as other posts have noted. Remove the Controller's XML config and do the following:

Since the success and failure URLs are not really configuration values, but are defined in your app, move those either 1) directly into the handler method as hard-coded values, or 2) if they are common to more than 1 method or Controller, move them as constants into a BaseController which all other Controllers extend. Then you avoid the DI issues for those two arguments altogether.

That leaves the baseCallbackUrl. If this is a value which is dependent on the application's URL, maybe make that value a system variable and directly inject it using @Value, as follows:

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


I think component scan is loading the Controller and you bean is loaded again because it is defined in the xml (bean id="socialAuthWebController").

Can you try commenting either component-scan or bean declaration? <context:component-scan base-package="org.brickred.socialauth.spring.controller" />


Maybe try declaring the name of the values. See Spring Documentation

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

I think Spring might be having a problem because it doesn't know which String goes where. So you could use "name" or "index" to let it know.

From the link: "If no potential ambiguity exists in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments are supplied to the appropriate constructor when the bean is being instantiated"

There is an ambiguity since you are using all Strings.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号