Java @Autowired 在 Spring Security 中不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21869416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@Autowired not working in Spring Security
提问by Rob Johansen
I'm implementing Spring Security using Java configuration in my Spring Web MVC project, and for some reason the @Autowired
annotation is not injecting fields in my security config class. I found thisvery similar question on SO, but my setup is muchsimpler and the accepted answer doesn't apply at all in my case.
我在 Spring Web MVC 项目中使用 Java 配置实现 Spring Security,并且由于某种原因,@Autowired
注释没有在我的安全配置类中注入字段。我在 SO 上发现了这个非常相似的问题,但是我的设置要简单得多,并且接受的答案在我的情况下根本不适用。
For reference, I followed the first three chapters of Spring's own security documentation (here) and got in-memory authentication working pretty quickly. I then wanted to switch to JDBC authentication and inject a DataSource
with the @Autowired
annotation (as shown in this example). However, I get this error:
作为参考,我遵循了 Spring 自己的安全文档(此处)的前三章,并很快使内存中的身份验证工作。然后我想切换到 JDBC 身份验证并注入DataSource
带有@Autowired
注释的 a(如本例所示)。但是,我收到此错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private javax.sql.DataSource com.tyedart.web.config.security.SecurityConfig.dataSource; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Here is my security config class. As you can see I'm working around the problem by explicitly looking up my data source:
这是我的安全配置类。正如您所看到的,我正在通过显式查找我的数据源来解决这个问题:
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
// @Autowired
// private DataSource dataSource;
// @Autowired
// public PasswordEncoder passwordEncoder;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
InitialContext ctx = new InitialContext();
DataSource dataSource = (DataSource) ctx.lookup("java:/comp/env/jdbc/TyedArtDB");
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
auth
.jdbcAuthentication()
.dataSource(dataSource)
.passwordEncoder(passwordEncoder);
}
@Override
public void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/manage/**").hasRole("ADMIN")
.and()
.formLogin();
}
}
And here is my very simple root-context.xml:
这是我非常简单的 root-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/TyedArtDB"/>
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>
</beans>
What am I doing wrong?
我究竟做错了什么?
回答by Nabarun
Add <context:component-scan base-package="your.package.where.your.bean.is"/>
in root-context.xml
<context:component-scan base-package="your.package.where.your.bean.is"/>
在 root-context.xml 中添加
You can uncomment the @Autowired in field declaration and remove it from the constractor. You can find more info here
您可以取消注释字段声明中的 @Autowired 并将其从构造函数中删除。你可以在这里找到更多信息
If you @Autowired
a bean, don't forget to remove the initialization using new
.
如果您@Autowired
是 bean,请不要忘记使用new
.
回答by rhinds
I'm not 100% sure, but it looks like the problem is you are trying to Autowire DataSource, which has not actually been defined as a Spring bean:
我不是 100% 确定,但看起来问题是您正在尝试 Autowire DataSource,它实际上并未被定义为 Spring bean:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/TyedArtDB"/>
Creates an object that can be referenced in XML, but don't think it actually creates a bean? (could be wrong, don't really do much with JNDI lookups in spring).
创建一个可以在 XML 中引用的对象,但不认为它实际上创建了一个 bean?(可能是错误的,在 spring 中不要对 JNDI 查找做太多事情)。
Is it possible to switch over to pure java config and drop the XML references?
是否可以切换到纯 Java 配置并删除 XML 引用?
@Bean
public DataSource dataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("jdbc/TyedArtDB");
}
(taken from this answer: https://stackoverflow.com/a/15440797/258813)
(取自这个答案:https: //stackoverflow.com/a/15440797/258813)
And you can move the password encoder like this:
您可以像这样移动密码编码器:
@Bean public BCryptPasswordEncoder bCryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}
taken from: http://automateddeveloper.blogspot.co.uk/2014/02/spring-4-xml-to-annotation-configuration.html
取自:http: //automateddeveloper.blogspot.co.uk/2014/02/spring-4-xml-to-annotation-configuration.html
回答by Sarvar Nishonboev
Here's an example I used to autowire BCryptPasswordEncoder:
这是我用来自动装配 BCryptPasswordEncoder 的示例:
UserServiceImpl.java
UserServiceImpl.java
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
BCryptPasswordEncoder bCryptPasswordEncoder;
@Override
public User findUserByEmail(String email) {
return null;
}
}
WebMvcConfig.java
WebMvcConfig.java
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Bean
public BCryptPasswordEncoder passwordEncoder(){
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}
If you notice, WebMvcConfig.java has @Bean annotation just before passwordEncoder() method. It indicates that a method produces a bean to be managed by the Spring container.
如果您注意到,WebMvcConfig.java 在 passwordEncoder() 方法之前有 @Bean 注释。它表示一个方法产生一个由 Spring 容器管理的 bean。