首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当使用JSR330提供程序时,线程Beans不会在春季获得环境@自动访问

当使用JSR330提供程序时,线程Beans不会在春季获得环境@自动访问
EN

Stack Overflow用户
提问于 2017-07-13 09:30:58
回答 1查看 641关注 0票数 1

希望这个问题是不言而喻的

ClassA.java

代码语言:javascript
复制
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ClassA implements InterB {
    private static int counter=0;

    private int objectid = 0;
    @Autowired
    InterA abcd;

    public ClassA() {
        super();
        this.objectid = ++counter;
    }

    @Override
    public void dododo() {
        System.out.println("instance number "+objectid++);
        abcd.doit();
    }
}

ClassB.java

代码语言:javascript
复制
@Component
@Conditional(OracleDBEngineCondition.class)
public class ClassB extends DummyParent implements InterA {
    @Autowired
    private Environment env;

    @Override
    public void doit() {
        System.out.println("hoo hoo" +" -- "+env.getProperty("DBENGINE"));
    }

}

ClassC.java

代码语言:javascript
复制
@Component("classc")
public class ClassC implements Runnable {

    @Autowired
    Provider<InterB> classAPrototypeobj;

    public void doFromAbove() {
        InterB cls = (InterB) classAPrototypeobj.get();
        InterB cls1 = (InterB) classAPrototypeobj.get();
        cls.dododo();
        cls1.dododo();
        System.out.println(cls);
        System.out.println(cls1);

    }

    @Override
    public void run() {
        this.doFromAbove();
    }
}

ClassConfig.java

代码语言:javascript
复制
@Configuration
@ComponentScan
public class ClassConfig {
}

主要方法

代码语言:javascript
复制
public static void main(String[] args) {
    ClassC obj;
    try(AbstractApplicationContext appctx = new AnnotationConfigApplicationContext(ClassConfig.class)) {
        obj = (ClassC) appctx.getBean("classc");
    }
    Thread objThread = new Thread(obj);
    objThread.start();
}

更新的主要方法(仍然有相同的问题)

代码语言:javascript
复制
public static void main(String[] args) {
    try(AbstractApplicationContext appctx = new AnnotationConfigApplicationContext(ClassConfig.class)) {
        ClassC obj = (ClassC) appctx.getBean("classc");
        Thread objThread = new Thread(obj);
        objThread.start();
    }
}

执行时,这会导致bean‘环境’的NoSuchBeanDefinitionException

但是,当我们在Config类中定义以下内容时,错误就会消失而不会有任何跟踪。--这是解决办法(但是Spring应该自动注入环境,我们不应该这样做),。不确定有多少这样的bean没有被注入/@Autowired

代码语言:javascript
复制
@Bean
public Environment environment(ApplicationContext context) {
    return context.getEnvironment();
}

我怀疑这是一个Spring框架错误..。不是吗?

StackTrace:

代码语言:javascript
复制
Exception in thread "Thread-1" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'classA': Unsatisfied dependency expressed through field 'abcd'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'classB': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' available
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:325)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.getObject(DefaultListableBeanFactory.java:1630)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory$Jsr330DependencyProvider.get(DefaultListableBeanFactory.java:1699)
    at tpt.verifypoc.ClassC.doFromAbove(ClassC.java:28)
    at tpt.verifypoc.ClassC.run(ClassC.java:39)
    at java.lang.Thread.run(Thread.java:745)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'classB': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' available
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
    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:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1138)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
    ... 14 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'environment' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1207)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:284)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$ShortcutDependencyDescriptor.resolveShortcut(AutowiredAnnotationBeanPostProcessor.java:740)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1077)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.resolvedCachedArgument(AutowiredAnnotationBeanPostProcessor.java:548)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.access$200(AutowiredAnnotationBeanPostProcessor.java:117)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:577)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
    ... 25 more

注:

  1. 春季:4.3.9
  2. JSR330: javax.inject版本1
EN

回答 1

Stack Overflow用户

发布于 2017-07-13 12:28:03

我想说,在您开始使用关闭ApplicationContext的对象之前,这不是Spring中的一个bug。或者,实际上,使用资源进行尝试的块就是这样做的。

代码语言:javascript
复制
public static void main(String[] args) {
    ClassC obj;
    try(AbstractApplicationContext appctx = new AnnotationConfigApplicationContext(ClassConfig.class)) {
        obj = (ClassC) appctx.getBean("classc");
    }
    Thread objThread = new Thread(obj);
    objThread.start();
}

基本上和

代码语言:javascript
复制
public static void main(String[] args) {
    ClassC obj;
    AbstractApplicationContext appctx = new AnnotationConfigApplicationContext(ClassConfig.class)) {
        obj = (ClassC) appctx.getBean("classc");

    appctx.close();

    Thread objThread = new Thread(obj);
    objThread.start();
}

在使用对象之前,您正在关闭ApplicationContext。剩下的是一个ClassC实例,它有一个Provided<ClassB>的半支持代理,它需要上下文来查找某些bean。然而,它没有办法查找那些豆子,因为你从它下面的注册表。

当您关闭ApplicationContext时,您将关闭应用程序。我希望您仍然存在的对象现在是无效的,因为属于的容器被销毁了。

将代码与JDBC代码进行比较。您正在打开一个Connection,关闭连接,然后尝试在关闭的连接上准备一个语句。JDBC不允许这样做,因为Connection是关闭的,因此无效。

将它与Microsoft进行比较,您可以打开它,在工作表中工作,编写一个宏。关闭excel,并期望宏仍然运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45076679

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档