我正在将spring应用程序从XML配置转换为基于java的配置。我的代码中需要一个帮助。
以前我的XML配置如下
<authentication-manager id="myAuthenticationManager">
<authentication-provider user-service-ref="employeeImpl" />
</authentication-manager>
<beans:bean id="employeeImpl" class="com.my.employee.EmployeeImpl">
<beans:property name="dataSource">
<beans:ref bean="myDatasource" />
</beans:property>
<beans:property name="usersByUsernameQuery">
<beans:value>
SELECT client_id, client_secret, enabled FROM client WHERE client_id=?
</beans:value>
</beans:property>
<beans:property name="authoritiesByUsernameQuery">
<beans:value>
SELECT client_id, authority FROM authorities WHERE client_id = ?
</beans:value>
</beans:property>
</beans:bean>
<beans:bean id="myCredentialsTokenEndpointFilter" class="com.my.web.controller.MyCredentialsTokenEndpointFilter">
<beans:property name="authenticationManager" ref="myAuthenticationManager" />
<beans:property name="tokenMappingQuery">
<beans:value>INSERT INTO TOKEN_MAPPING (TOKEN_D, TOKEN_G) VALUES(?,?)</beans:value>
</beans:property>
<beans:property name="dataSource" ref="myDatasource" />
</beans:bean>
我尝试的Java配置如下..
我尝试调试代码,所以首先加载这个类
public class MyWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
@Override
protected Class<?>[] getRootConfigClasses()
{
return new Class[] { MyBeanConfiguration.class };
}
@Override
protected Class<?>[] getServletConfigClasses()
{
return new Class[] { MyViewConfig.class };
}
@Override
protected String[] getServletMappings()
{
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters()
{
return null;
}
}
然后调试来到这个类
@Configuration
@EnableWebMvcSecurity
@ComponentScan(basePackageClasses = EmployeeImpl.class)
public class MyWebSecurityConfigurator extends WebSecurityConfigurerAdapter
{
/*
* @Autowired Employee userDetailService;
*/
@Autowired
private DataSource dataSource;
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private EmployeeImpl employeeImpl;
@Override
protected void configure(HttpSecurity http) throws Exception
{
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().headers().cacheControl().contentTypeOptions().httpStrictTransportSecurity().and()
.requestMatchers().antMatchers("/myapp/auth").and().httpBasic().authenticationEntryPoint(getEntryPoint()).and()
.addFilterBefore(getTokenFilter(), BasicAuthenticationFilter.class).authorizeRequests().anyRequest().access("hasRole('ROLE_USER')");
}
public BasicAuthenticationEntryPoint getEntryPoint()
{
BasicAuthenticationEntryPoint entryPoint = new BasicAuthenticationEntryPoint();
entryPoint.setRealmName("My");
return entryPoint;
}
public MyCredentialsTokenEndpointFilter getTokenFilter() throws Exception
{
MyCredentialsTokenEndpointFilter tokenFilter = new MyCredentialsTokenEndpointFilter();
tokenFilter.setTokenMappingQuery("INSERT INTO TOKEN_MAPPING (TOKEN_D, TOKEN_G) VALUES(?,?)");
tokenFilter.setDataSource(dataSource);
tokenFilter.setAuthenticationManager(authenticationManager);
return tokenFilter;
}
@Autowired
public void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(employeeImpl);
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception
{
return super.authenticationManagerBean();
}
}
我的其他课程..
@Configuration
@ComponentScan
public class MyBeanConfiguration
{
@Autowired
private DataSource dataSource;
@Bean
public MyService myService()
{
return new myServiceImpl();
}
@Bean
public UserDetailsService employeeImpl()
{
EmployeeImpl employee = new EmployeeImpl();
employee.setDataSource(dataSource);
employee.setUsersByUsernameQuery("SELECT client_id, client_secret, enabled FROM my_client WHERE client_id=?");
employee.setAuthoritiesByUsernameQuery("SELECT client_id, authority FROM authorities WHERE client_id = ?");
return employee;
}
}
和
@Service
public class EmployeeImpl extends JdbcDaoImpl
{
@Autowired
private DataSource dataSource;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
{
System.out.println("Received UserName : " + username);
UserDetails user = super.loadUserByUsername(username);
MyUser myUser = new MyUser(username, user.getPassword(), user.isEnabled(), user.isAccountNonExpired(), user.isCredentialsNonExpired(), user.isAccountNonLocked(),
user.getAuthorities());
return myUser;
}
}
问题是每次调试到达configure(AuthenticationManagerBuilder auth) of MyWebSecurityConfigurator
类时,自动装配的变量employeeImpl总是为空,所以我得到的是异常......
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'MyWebSecurityConfigurator': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.my.employee.EmployeeImpl com.my.config.security.MyWebSecurityConfigurator.employeeImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeImpl' defined in file [D:\EclipseWS\Alfresco Research Portal\Research Portal\Spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringSecurity\WEB-INF\classes\com\my\employee\EmployeeImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:381)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:293)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4959)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.my.employee.EmployeeImpl com.my.config.security.MyWebSecurityConfigurator.employeeImpl; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'employeeImpl' defined in file [D:\EclipseWS\Alfresco Research Portal\Research Portal\Spring\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringSecurity\WEB-INF\classes\com\my\employee\EmployeeImpl.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 22 more
需要你的建议来了解我哪里出错了......不能理解我做错了什么..