【问题标题】:FactoryBeanNotInitializedException: Cannot determine target class for proxyFactoryBeanNotInitializedException:无法确定代理的目标类
【发布时间】:2014-06-30 23:20:00
【问题描述】:

我想在我的 spring 应用程序中设置一个仅带有注释的对象池。 我从 Spring 文档中的这个示例开始:http://docs.spring.io/spring/docs/2.5.x/reference/aop-api.html#aop-ts-pool

这是我翻译 XML 配置的方法:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class SpringObjectPoolTest {
    public static void main(String[] args) throws Exception {
        context = new SpringApplicationBuilder(SpringObjectPoolTest.class) //
                .addCommandLineProperties(false) //
                .web(false) //
                .headless(false) //
                .registerShutdownHook(true) //
                .application() //
                .run();

        context.getBean(SpringObjectPoolTest.class).go();
    }

    @Resource(name = "pfb")
    private FactoryBean<MyTask> pool;

    @Resource(name="pool")
    private TargetSource targetSource;

    private static ConfigurableApplicationContext context;

    @Bean(name = "task")
    @Scope("prototype")
    public MyTask createNewTask() {
        return new MyTask();
    }

    @Bean(name = "pool")
    public CommonsPoolTargetSource setupObjectPool() {
        CommonsPoolTargetSource pc = new CommonsPoolTargetSource();
        pc.setMaxSize(25);
        pc.setTargetBeanName("task");

        return pc;
    }

    @Bean(name = "pfb")
    public ProxyFactoryBean createProxyFactoryBean() {
        ProxyFactoryBean pfb = new ProxyFactoryBean();
        pfb.setTargetSource(targetSource);

        return pfb;
    }

    private void go() {
        try {
            pool.getObject().speak();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

但是我得到了这个异常:

org.springframework.beans.factory.BeanCurrentlyInCreationException: 
   Error creating bean with name 'pfb':  
org.springframework.beans.factory.FactoryBeanNotInitializedException: 
   Cannot determine target class for proxy

【问题讨论】:

    标签: java spring pool


    【解决方案1】:

    你有点过度设计这个。 Spring 已经知道如何注入代理的MyTask,不需要在池上拥有FactoryBean&lt;MyTask&gt; 或调用getObject()。在下面的“pooledTask”中,Spring 知道通过注入 ProxyFactoryBean ("pfb") 它实际上会注入工厂 bean 创建的实例,而不是工厂 bean 本身。以下是我的做法:

    @Configuration
    @EnableAutoConfiguration
    @ComponentScan
    public class SpringObjectPoolTest {
        public static void main(String[] args) throws Exception {
            context = new SpringApplicationBuilder(SpringObjectPoolTest.class) //
                    .addCommandLineProperties(false) //
                    .web(false) //
                    .headless(false) //
                    .registerShutdownHook(true) //
                    .application() //
                    .run();
    
            context.getBean(SpringObjectPoolTest.class).go();
        }
    
        private static ConfigurableApplicationContext context;
    
        @Resource(name = "pfb")
        private MyTask pooledTask;
    
        @Resource(name="pool")
        private CommonsPoolTargetSource targetSource;
    
        @Bean(name = "task")
        @Scope("prototype")
        public MyTask createNewTask() {
            return new MyTask();
        }
    
        @Bean(name = "pool")
        public CommonsPoolTargetSource setupObjectPool() {
            CommonsPoolTargetSource pc = new CommonsPoolTargetSource();
            pc.setMaxSize(25);
            pc.setTargetBeanName("task");
    
            return pc;
        }
    
        @Bean(name = "pfb")
        public ProxyFactoryBean createProxyFactoryBean() {
            ProxyFactoryBean pfb = new ProxyFactoryBean();
            pfb.setTargetSource(setupObjectPool());
    
            return pfb;
        }
    
        private void go() {
            try {
                pooledTask.speak();
    
                // getting another object from pool
                MyTask someOtherTask = (MyTask) targetSource.getTarget();
    
                // returning the object to the pool
            targetSource.releaseTarget(someOtherTask);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

    • 如何从池中获取多个对象并释放它们?
    • 您需要为此使用上下文:MyTask task = (MyTask) context.getBean("pfb");。每次调用getBean 都会从池中借用一个对象。要释放它们,您需要获取池对象并在其上调用 releaseTarget
    • 是否可以使用hold来借用对象而不是上下文?
    • 查看我的更新答案。我定义了一个要注入的新@Resource(name="pool"),并在“go()”方法中使用它。
    猜你喜欢
    • 1970-01-01
    • 2022-10-14
    • 2016-11-02
    • 2018-12-15
    • 2019-01-30
    • 2018-01-08
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多