Spring @autowired不适用于非单件容器吗?

 yangwei的马甲 发布于 2023-02-07 10:38

我有一个MyTask实现的类,Runnable并且可以在任何给定时刻实例化许多这样的对象.有些属性我想自动MyTask上课.

但我认为,如果我MyTask@Component它标记它将成为一个弹簧管理的单身正确吗?这不是我想要的,我需要由TaskExecutor运行这个类的许多独立实例.

所以我的问题:

a)我对@Component注释的理解从根本上是错误的吗?它不会MyTask成为一个由春季管理的单身人士吗?

b)我应该使用其他注释,以便spring检测@Autowired并注入属性吗?

c)弹簧自动装配不适用于非单件容器/类MyTask吗?


更新#1 - 这些不起作用:

public class MyTask implements Runnable { // I want this class to be non-singleton
    @Autowired
    public SomeSpecialSpringConfiguredConnectionClass blah; // this is the singleton bean that should be injected
    @Override
    public void run() {
        // BLAH IS NULL, this shouldn't be NULL, that is not what I want
        // which makes sense considering Spring never knew it had to work
        // on this class
    }
}

@Component
public class MyTask implements Runnable { // I want this class to be non-singleton
    @Autowired
    public SomeSpecialSpringConfiguredConnectionClass blah; // this is the singleton bean that should be injected
    @Override
    public void run() {
        // this works BUT now MyTask is singleton :(
    }
}

@Component
@Scope("prototype")
public class MyTask implements Runnable { // I want this class to be non-singleton
    @Autowired
    public SomeSpecialSpringConfiguredConnectionClass blah; // this is the singleton bean that should be injected
    @Override
    public void run() {
        // BLAH IS NULL, again ... this shouldn't be NULL, that is not what I want
    }
}

更新#2 - 在等待更多关于如何做到这一点的建议时,我正在研究:Using AspectJ to dependency inject domain objects with Spring作为替代方案.

2 个回答
  • 首先,默认情况下,使用@Component声明并由弹簧组件扫描拾取的bean将成为弹簧管理的单例.

    我不知道你如何使用MyTask,但在你的情况下使用AspectJ是过分的,将MyTask声明为一个弹簧管理的bean没有多大意义.另一种方法是:

      将MyTask定义为普通java类,并添加构造函数以初始化依赖项blah

      autowire blah在你使用的地方MyTask,并在每次要执行任务时实例化MyTask对象,如下所示:

      //autowire the dependency of MyTask in another spring bean with default singleton scope
      @Autowired private SomeSpecialSpringConfiguredConnectionClass blah
      //create task and wire the blah yourself
      executor.submit(new MyTask(blah))
      

    2023-02-07 10:39 回答
  • @Component注释允许它们在使用上下文进行类路径扫描时进行自动检测:组件扫描就是这样做的.@Service和@Component之间有一条细线,在这种情况下它无论如何都不会影响.

    弹簧自动装配可以用于原型和单件范围.在原型范围的情况下,虽然没有调用bean的销毁的生命周期回调.

    它在Spring文档页面上得到了很好的解释. http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

    我没有看到为什么你提到的任何东西不应该工作的原因.

    他是我试图更好地解释它的工作样本.

    public class SpringContainerStartClass {
    
       public static void main(final String[] args) {
          final ClassPathXmlApplicationContext bf = new ClassPathXmlApplicationContext("beans.xml");
          final MainApplication1 bean = (MainApplication1) bf.getBean("mainApplication1");
          bean.getMyTask().printSomething();
    
       }
    }
    

    这是应用程序的起点.

    这是你的myTask类

    @Component(value = "myTask")
    @Scope(value = "prototype")
    public class MyTask
          implements Runnable {
    
       @Autowired
       private SomeSpecialSpringConfiguredConnectionClass someSpringObject;
    
       @Override
       public void run() {
          System.out.println("running now");
    
       }
    
       public void printSomething() {
          System.out.println(someSpringObject.getValue());
       }
    
       public SomeSpecialSpringConfiguredConnectionClass getSomeSpringObject() {
          return someSpringObject;
       }
    
       public void setSomeSpringObject(final SomeSpecialSpringConfiguredConnectionClass someSpringObject) {
          this.someSpringObject = someSpringObject;
       }
    
    }
    

    另外两个类来展示原型范围是如何工作的

    @Component
    public class MainApplication1 {
    
       @Autowired
       private MyTask myTask;
    
       public MyTask getMyTask() {
          return myTask;
       }
    
       public void setMyTask(final MyTask myTask) {
          this.myTask = myTask;
       }
    
    }
    
    @Component
    public class MainApplication2 {
    
       @Autowired
       private MyTask myTask;
    
       public MyTask getMyTask() {
          return myTask;
       }
    
       public void setMyTask(final MyTask myTask) {
          this.myTask = myTask;
       }
    
    }
    

    一个BeanPostprocessor,它将向您展示如何创建对象

    public class InstantiationTracingBeanPostProcessor
          implements BeanPostProcessor {
    
       @Override
       public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
          return bean;
       }
    
       @Override
       public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
          System.out.println("Bean '" + beanName + "' created : " + bean.toString());
          return bean;
       }
    }
    

    你的SomeSpringConfig类

    @Service
    public class SomeSpecialSpringConfiguredConnectionClass {
    
       private String value = "someValue";
    
       public String getValue() {
          return value;
       }
    
       public void setValue(final String value) {
          this.value = value;
       }
    
    }
    

    运行此示例时,您会注意到控制台上的输出是

    INFO: Loading XML bean definitions from class path resource [beans.xml]
    Jan 02, 2014 12:07:15 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@26efabf8: defining beans [mainApplication1,mainApplication2,myTask,someSpecialSpringConfiguredConnectionClass,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,com.stackoverflow.DIQuestion.InstantiationTracingBeanPostProcessor#0,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
    Bean 'someSpecialSpringConfiguredConnectionClass' created : com.stackoverflow.DIQuestion.SomeSpecialSpringConfiguredConnectionClass@1e20d04b
    Bean 'myTask' created : com.stackoverflow.DIQuestion.MyTask@175d6331
    Bean 'mainApplication1' created : com.stackoverflow.DIQuestion.MainApplication1@741b31f2
    Bean 'myTask' created : com.stackoverflow.DIQuestion.MyTask@2c2815d3
    Bean 'mainApplication2' created : com.stackoverflow.DIQuestion.MainApplication2@7bb0e64a
    

    如果您注意到carefulyy,则myTask中有2个对象具有不同的哈希码.

    如果你将myTask的范围更改为"Singleton",那么这将是输出.

    INFO: Loading XML bean definitions from class path resource [beans.xml]
    Jan 02, 2014 12:08:35 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
    INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@26efabf8: defining beans [mainApplication1,mainApplication2,myTask,someSpecialSpringConfiguredConnectionClass,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,com.stackoverflow.DIQuestion.InstantiationTracingBeanPostProcessor#0,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
    Bean 'someSpecialSpringConfiguredConnectionClass' created : com.stackoverflow.DIQuestion.SomeSpecialSpringConfiguredConnectionClass@1e20d04b
    Bean 'myTask' created : com.stackoverflow.DIQuestion.MyTask@175d6331
    Bean 'mainApplication1' created : com.stackoverflow.DIQuestion.MainApplication1@741b31f2
    Bean 'mainApplication2' created : com.stackoverflow.DIQuestion.MainApplication2@2c2815d3
    

    在这种情况下,为"myTask"创建了一个对象

    这有帮助吗?

    2023-02-07 10:40 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有