Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将动态创建的实例用作Spring autowiring中使用的bean_Java_Spring - Fatal编程技术网

Java 如何将动态创建的实例用作Spring autowiring中使用的bean

Java 如何将动态创建的实例用作Spring autowiring中使用的bean,java,spring,Java,Spring,在注释ConfigWebApplicationContext中,我有一些特定实例需要用于自动布线。下面是演示错误的代码。当然,我的情况要复杂得多,实例是在运行时确定的。我在spring配置时发现了这些实例,这就是为什么如果下面的代码能够工作,就可以了。我试过了,但是它抛出了NoSuchBeanDefinitionException,即使ctx.getBean能够找到它。实现这一目标的正确方法是什么 import org.springframework.beans.factory.annotati

注释ConfigWebApplicationContext
中,我有一些特定实例需要用于自动布线。下面是演示错误的代码。当然,我的情况要复杂得多,实例是在运行时确定的。我在spring配置时发现了这些实例,这就是为什么如果下面的代码能够工作,就可以了。我试过了,但是它抛出了
NoSuchBeanDefinitionException
,即使
ctx.getBean
能够找到它。实现这一目标的正确方法是什么

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

class Scratch {
    static class MyClass {
    }

    @Configuration
    static class TestConfig {
        @Autowired
        private MyClass myClass;
    }

    public static void main(String[] args) {
        MyClass requiredInstance = new MyClass();
        final AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.refresh(); // Throws "BeanFactory not initialized..." on next line if this not here
        ctx.getBeanFactory().registerSingleton("myClass", requiredInstance);
        // Also tried: ((DefaultListableBeanFactory)ctx.getAutowireCapableBeanFactory()).registerSingleton("myClass", requiredInstance);
        System.out.println(ctx.getBean(MyClass.class)); // Outputs "Scratch$MyClass@1804f60d"
        ctx.register(TestConfig.class);
        ctx.refresh(); // Throws "NoSuchBeanDefinitionException: No qualifying bean of type 'Scratch$MyClass' available:"
    }
}
在这里找到了一个解决方案。我在别处看到过BeanFactoryPostProcessor,但他们没有展示如何创建实例。这个例子展示了我所需要的工厂机制

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

class Scratch {
    static class MyClass {
    }

    @Configuration
    static class TestConfig {
        @Autowired
        private MyClass myClass;
    }

    public static void main(String[] args) {
        final AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(TestConfig.class);
        ctx.register(DynamicBeanFactoryProcessor.class);
        ctx.refresh();
        System.out.println(ctx.getBean("myClass")); // Outputs "Scratch$MyClass@1804f60d"
        System.out.println(ctx.getBean(MyClass.class)); // Outputs "Scratch$MyClass@1804f60d"
    }

    @Configuration
    public static class DynamicBeanFactoryProcessor implements BeanFactoryPostProcessor {
        public <T> T createInstance(Class<T> c) {
            return c.cast(new MyClass()); // Create dynamic instance here
        }

        @Bean
        public DynamicBeanFactoryProcessor dynamicBeanFactoryProcessor() {
            return new DynamicBeanFactoryProcessor();
        }

        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            ((BeanDefinitionRegistry)beanFactory).registerBeanDefinition("myClass",
                    BeanDefinitionBuilder.genericBeanDefinition(MyClass.class)
                        .setFactoryMethodOnBean("createInstance", "dynamicBeanFactoryProcessor")
                        .addConstructorArgValue(MyClass.class)
                        .getBeanDefinition());
        }
    }
}
import org.springframework.beans.BeansException;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.beans.factory.config.BeanFactoryPostProcessor;
导入org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
导入org.springframework.beans.factory.support.BeanDefinitionBuilder;
导入org.springframework.beans.factory.support.BeanDefinitionRegistry;
导入org.springframework.context.annotation.Bean;
导入org.springframework.context.annotation.Configuration;
导入org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
课堂擦伤{
静态类MyClass{
}
@配置
静态类TestConfig{
@自动连线
私人MyClass MyClass;
}
公共静态void main(字符串[]args){
最终注释ConfigWebApplicationContext ctx=新注释ConfigWebApplicationContext();
寄存器(TestConfig.class);
寄存器(DynamicBeanFactoryProcessor.class);
ctx.refresh();
System.out.println(ctx.getBean(“myClass”);//输出“Scratch”$MyClass@1804f60d"
System.out.println(ctx.getBean(MyClass.class));//输出“Scratch”$MyClass@1804f60d"
}
@配置
公共静态类DynamicBeanFactoryProcessor实现BeanFactoryPostProcessor{
公共T createInstance(c类){
返回c.cast(new MyClass());//在此处创建动态实例
}
@豆子
公共DynamicBeanFactoryProcessor DynamicBeanFactoryProcessor(){
返回新的DynamicBeanFactoryProcessor();
}
@凌驾
public void后处理beanFactory(ConfigurableListableBeanFactory beanFactory)引发BeanException{
((BeanDefinitionRegistry)beanFactory).registerBeanDefinition(“myClass”,
BeanDefinitionBuilder.genericBeanDefinition(MyClass.class)
.setFactoryMethodOnBean(“createInstance”、“dynamicBeanFactoryProcessor”)
.addConstructorArgValue(MyClass.class)
.getBeanDefinition());
}
}
}

当您刷新
一个
注释ConfigWebApplicationContext
时,它会清除其底层
BeanFactory
并创建一个新的,并使用新的来初始化bean。
MyClass
bean之后将无法用于注入。当通过
@Configuration
层次结构没有可用的
MyClass
bean时,拥有一个依赖于
MyClass
TestConfig
是没有意义的。好吧,那么我有没有办法配置一个bean工厂类型的东西,可以在配置过程中注入我需要的实例?