使用非SpringBoot托管的构造函数参数自动装配类

时间:2019-02-27 11:05:26

标签: java spring-boot

顾名思义,您如何Autowire使用非SpringBoot托管类作为构造函数args的类。

以下是说明此问题的代码块:

@Component
class Prototype
{
    @Autowired
    private Repository repository;

    private NonSpringBootManagedBean bean;

    Prototype(NonSpringBootManagedBean bean)
    {
        this.bean = bean;
    }
}

@Component
class PrototypeClient
{
    @Autowired
    private ApplicationContext context;

    private void createNewPrototype(NonSpringBootManagedBean bean)
    {

        // This throws an error saying no bean of type NonSpringBootManangedBean found
        Prototype prototype = context.getBean(Prototype.class, bean);
    }
}

我使用ApplicationContext而不是使用Prototype来获取@Autowired实例的原因是因为我需要在方法{{1中使用Prototype }}每次调用它而不是一个单例实例(另外,请告知这种获取新实例的方法是否不正确)。

更新: 正如其他人所述,将我的bean创建移至Java配置类,并添加由createNewPrototype()注释的方法,并在@Bean方法中实例化NonSpringBootManagedBean。但是我认为这是不可能的,因为@Bean的调用者传递了此NonSpringBootManagedBean

更新 我已经更清楚地更新了上面的代码示例。请现在参考。

PrototypeClient.createNewPrototype()

3 个答案:

答案 0 :(得分:1)

您知道您可以将bean范围更改为原型引用而不是单例。这样,您可以将单个bean定义的作用域限定为任意数量的对象实例。

https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

private NonSpringBootManagedBean bean = new NonSpringBootManagedBean();

@Bean
public Prototype getPrototype(){
  return new Prototype(bean);
}

答案 1 :(得分:0)

Spring无法自动装配对象(如果不知道)。在某些需要@Component或@Bean或其他批注(例如@Service等)的地方,要告诉spring管理实例。

还建议,如果您在Autowire中使用私有变量,则应将其作为构造函数的一部分(用于构造函数注入)或必须提供setter方法(setter注入)

要解决您的错误:您可以创建一个Java config类并将其放在基础pkg中(与@SpringBootApplication相同,或在具有@SpringBootApplication的类上添加@ComponentScan(“其中存在配置的pkg”))

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

    @Configuration
    public class myconfig {

        @Bean
        public NonSpringBootManagedBean nonSpringBootManagedBean()
        {
            return new NonSpringBootManagedBean();

        }

    }

答案 2 :(得分:0)

定义一个范围为 prototype

的bean

这是每次作为新实例注入的。 在 SpringBoot 中,您可以将注释 @Scope("prototype")用于bean类Prototype

@Component
@Scope("prototype")
class Prototype {

    @Autowired
    private Repository repository;

    private NonSpringBootManagedBean bean;

    Prototype() {
        // you can only modify this 'NonSpringBootManagedBean' later
        // because Spring calls constructor without knowing NonSpringBootManagedBean  
        this.bean = new NonSpringBootManagedBean();

        // do something with 'repository' because its defined
    }

    public void setNonSpringBootManagedBean(NonSpringBootManagedBean bean) {
        this.bean = bean;        
    }        
}

使用此bean的实例

通过注入(例如,@Autowired到构造函数),您可以在其他bean中使用该原型bean的不同实例。

@Component
class PrototypeClient {
    // ApplicationContext still used?
    @Autowired
    private ApplicationContext context;

    private Prototype prototypeInstance;

    @Autowired  // injects the new instance of Prototype
    public PrototypeClient(Prototype p)
        this.prototypeInstance = p;

        // here you can change the NSBMB
        modifyPrototype();
    }

    private void modifyPrototype(NonSpringBootManagedBean bean) {
         this.prototypeInstance.setNonSpringBootManagedBean( new NonSpringBootManagedBean() );
    }
}

为什么会引发您的异常?

  

未找到NonSpringBootManangedBean类型的bean

Spring尝试实例化Prototype类型的Bean时抱怨

Prototype prototype = context.getBean(Prototype.class, bean);

由于要调用其构造函数,因此需要传递NonSpringBootManagedBean类型的参数。由于所有此类bean实例化都是由Spring(Boot)在内部完成的,因此您无法像在方法createNewPrototype(NonSpringBootManagedBean bean)中所尝试的那样截取并告诉Spring:“嘿,请使用此类NonSpringBootManagedBean的bean”。

为什么Spring(Boot)无法将NonSpringBootManagedBean作为bean管理?

SpringBoot中的

自动装配依赖注入的一种方式。这意味着SpringBoot之前已经在启动时自动实例化了bean(在Spring引导时)。现在,此bean作为依赖项注入到另一个bean等中,因为另一个bean依赖于它。

如果您告诉我们更多背景信息,我们可能会为您提供更多信息。这可以是以下答案:

  1. 什么是 NonSpringBootManagedBean ?为什么没有托管的豆
  2. 什么是 Prototype (原型),它使用 NonSpringBootManagedBean 是什么目的?
  3. 什么是 PrototypeClient ,为什么要创建自己的 Prototype

我不确定我是否了解您的对象/类之间的关系和目的。