【发布时间】:2016-12-21 14:54:27
【问题描述】:
我正在尝试将一个简单的字符串作为构造函数 arg 注入到扩展 org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint 的 bean 中。这是课程:
@Component
public class AuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
public AuthenticationEntryPoint(String url) {
super(url);
}
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
在我的 security-context.xml 中,我将我的 bean 定义如下:
<beans:bean id="authenticationEntryPoint" class="a.b.s.AuthenticationEntryPoint" >
<beans:constructor-arg index="0" type="java.lang.String" value="/login"/>
</beans:bean>
据我所知,这应该可以,但我收到以下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'authenticationEntryPoint' defined in file [/a/b/c/d/target/app/WEB-INF/classes/a/b/s/AuthenticationEntryPoint.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
奇怪的是它适用于以下配置:
<beans:bean id="loginUrl" class="java.lang.String">
<beans:constructor-arg value="/login"/>
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="a.b.s.AuthenticationEntryPoint" >
<beans:constructor-arg index="0" type="java.lang.String" value="/login"/>
</beans:bean>
所以,只声明一个 String bean 而不使用它就可以运行应用程序。有人可以向我解释为什么会这样吗?
L.E:我正在使用 Spring context 4.3.0 和 Spring security 4.1.0
修复: 因为它是在 xml 中定义的并且还使用@Component 进行了注释,所以 Spring 会生成 2 个相同类型的实例,所以当 Spring 在扫描包时尝试调用构造函数并且它没有自动装配的字符串作为构造函数 arg 传递时,就会出现错误。我通过简单地从 AuthenticationEntryPoint 类中删除 @Component 来解决它。
我们现在可以删除这篇文章了
【问题讨论】:
-
我假设您已启用组件扫描?在这种情况下,
@Component-annotated bean 定义首先被提取,尝试使用@Named或@Value使用注解配置注入字符串。 -
哦,愚蠢的我,我在阅读您的评论时发现了它。因为它是在 xml 中定义的并且还使用
@Component进行注释,所以 Spring 会生成 2 个相同类型的实例,因此当 Spring 在扫描包时尝试调用构造函数并且它没有自动装配的字符串作为构造函数 arg 传递时,就会出现错误。我通过简单地从AuthenticationEntryPoint类中删除@Component来解决它。谢谢@mszymborski -
如果您不介意,我会将其作为答案发布,以免污染“未回答”部分。
标签: java spring spring-security