简体   繁体   中英

Spring - trouble with injecting validator bean

i couldn't find solution for my problem anywhere. I'm trying to make validation working in spring web flow form. I need to set validator in configuration, however it's located in another config file and it seems spring can't find proper bean. How can I achieve successful injection here? As far as I know, Autowiring should inject bean into validator reference. Maybe it has something to do with order of loading configuration classes?

WebConfig.java:

@Configuration
@Import(godziszewski.patryk.ElectronicsStore.config.FlowConfiguration.class)
@EnableWebMvc
@ComponentScan(basePackages = "godziszewski.patryk")
public class WebConfig extends WebMvcConfigurerAdapter {
    ....
    @Bean
    public LocalValidatorFactoryBean validator()
    {
        LocalValidatorFactoryBean lv = new LocalValidatorFactoryBean();
        lv.setValidationMessageSource(messageSource());
        return lv;
    }
}

FlowConfiguration.java:

@Configuration
public class FlowConfiguration extends AbstractFlowConfiguration {
    @Autowired
    Validator validator;
    ....

    @Bean
    public FlowBuilderServices flowBuilderServices()
    {
        FlowBuilderServices fbs = new FlowBuilderServices();
        fbs.setValidator(validator);
        return fbs;
    }
}

The error i'm getting:

org.springframework.beans.factory.UnsatisfiedDependencyException: 
  Error creating bean with name 'flowConfiguration': 
  Unsatisfied dependency expressed through field 'validator': 
  No qualifying bean of type [org.springframework.validation.Validator] found for dependency [org.springframework.validation.Validator]: 
  expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)};
  nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
    No qualifying bean of type [org.springframework.validation.Validator] found for dependency [org.springframework.validation.Validator]: 
    expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Im using spring 4.3.2.RELEASE

However, when I delete Validator dependency from FlowAdapter.class I get error :

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'flowBuilderServices' defined in class path resource [godziszewski/patryk/ElectronicsStore/config/FlowConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: The ViewFactoryCreator is required
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:381)
    at godziszewski.patryk.ElectronicsStore.config.FlowConfiguration$$EnhancerBySpringCGLIB$$b65e14d6.flowBuilderServices(<generated>)
    at godziszewski.patryk.ElectronicsStore.config.FlowConfiguration.flowRegistry(FlowConfiguration.java:25)
    at godziszewski.patryk.ElectronicsStore.config.FlowConfiguration$$EnhancerBySpringCGLIB$$b65e14d6.CGLIB$flowRegistry$3(<generated>)
    at godziszewski.patryk.ElectronicsStore.config.FlowConfiguration$$EnhancerBySpringCGLIB$$b65e14d6$$FastClassBySpringCGLIB$$e5741e7e.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:356)
    at godziszewski.patryk.ElectronicsStore.config.FlowConfiguration$$EnhancerBySpringCGLIB$$b65e14d6.flowRegistry(<generated>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
    ... 24 more
Caused by: java.lang.IllegalArgumentException: The ViewFactoryCreator is required

Full FlowConfiguration class code, maybe I'm doing something wrong?

package godziszewski.patryk.ElectronicsStore.config;



import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.webflow.config.AbstractFlowConfiguration;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
import org.springframework.webflow.executor.FlowExecutor;
import org.springframework.webflow.mvc.servlet.FlowHandlerAdapter;
import org.springframework.webflow.mvc.servlet.FlowHandlerMapping;


@Configuration
public class FlowConfiguration extends AbstractFlowConfiguration {


    @Bean
    public FlowDefinitionRegistry flowRegistry() {
        return getFlowDefinitionRegistryBuilder()
            .setBasePath("/WEB-INF/flows")
            .setFlowBuilderServices(flowBuilderServices())
            .addFlowLocationPattern("/**/*-flow.xml")
            .build();
    }
    @Bean
    public FlowExecutor flowExecutor() {
        return getFlowExecutorBuilder(flowRegistry()).build();
    }

    @Bean
    public FlowHandlerMapping flowHandlerMapping()
    {
        System.out.println("flowconfig");
        FlowHandlerMapping fh = new FlowHandlerMapping();
        fh.setFlowRegistry(flowRegistry());
        return fh;
    }
    @Bean
    public FlowHandlerAdapter flowHandlerAdapter()
    {
        FlowHandlerAdapter fh = new FlowHandlerAdapter();
        fh.setFlowExecutor(flowExecutor());
        return fh;
    }
    @Bean
    public FlowBuilderServices flowBuilderServices()
    {
        FlowBuilderServices fbs = new FlowBuilderServices();
        //fbs.setValidator(validator);
        return fbs;
    }
}

If i delete .setFlowBuilderServices(flowBuilderServices()) method, everything works fine

EDIT: I managed to get this working by deleting @Configuration annotation form flow config class, now it looks like this:

//@Configuration
public class FlowConfiguration extends AbstractFlowConfiguration {

    @Autowired
    Validator validator;

    ...
    @Bean
    public FlowBuilderServices flowBuilderServices()
    {
        System.out.println(validator.toString());
        FlowBuilderServices fbs = new FlowBuilderServices();
        fbs.setValidator(validator);
        return fbs;
    }

And now I can use injected LocalValidatorBean in this class.

I interpret that eventually you need a FlowBuilderServices which has a reference to Validator bean.

This can be achieved by using the Autowired tag inside FlowBuilderServices

public class FlowBuilderServices{
@Autowired
Validator validator

...
}

And then in FlowConfiguration you just need to define the bean

@Bean
public class FlowBuilderServices flowBuilderServices()
    {
        FlowBuilderServices fbs = new FlowBuilderServices();
        return fbs;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM