Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

207
Visualizações
How to inject dependencies in spring for objects created dynamically at run time?
public class PlatformEventFactory {

    public PlatformEvent createEvent(String eventType) {
        if (eventType.equals("deployment_activity")) {
            return new UdeployEvent();
        }


        return null;
    }
}

I have a factory class which creates PlatformEvent type objects based on the eventType.

UdeployEvent class has dependency on private RedisTemplate<String, Object> template on which I want to inject after the UdeployEvent object has been created.

@Component
public class UdeployEvent implements PlatformEvent {

    private RedisTemplate<String, Object> template;
    private UDeployMessage uDeployMessage;

    private static final Logger logger = LoggerFactory.getLogger(UdeployEvent.class);

    public UdeployEvent() {
        uDeployMessage = new UDeployMessage();
    }


    /*public void sendNotification() {

    }*/

    public RedisTemplate<String, Object> getTemplate() {
        return template;
    }

    @Autowired
    public void setTemplate(RedisTemplate<String, Object> template) {
        this.template = template;
        System.out.println("Injection done");
    }
}

When the new object is returned for UdeployEvent I get null pointer exception for template. I believe the reason for that is because it is not referring to the same bean which is created when spring boots up. How can I inject dependencides for newly created objects at run time.

about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

You should not create components manually. Let Spring to do this. Use ApplicationContext to get instance of component. All fields will be automatically injected:

@Component
public class PlatformEventFactory {

    @Autowired
    private ApplicationContext context;

    public PlatformEvent createEvent(String eventType) {
        if (eventType.equals("deployment_activity")) {                
            return context.getBean(UdeployEvent.class);
        }

        return null;
    }
}

To make Spring create new instance of UdeployEvent component every time you request it, specify scope of component as SCOPE_PROTOTYPE:

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class UdeployEvent implements PlatformEvent {

    private RedisTemplate<String, Object> template;

    public RedisTemplate<String, Object> getTemplate() {
        return template;
    }

    @Autowired
    public void setTemplate(RedisTemplate<String, Object> template) {
        this.template = template;
        System.out.println("Injection done");
    }

    ...
}

Now every time you call context.getBean(UdeployEvent.class) Spring will create new instance of component with fully initialized dependencies.

about 4 years ago · Santiago Trujillo Relatório

0

When you're creating objects by hand, dependency injection is not performed in created object, and the field is null.

The easy way would be to use AutowireCapableBeanFactory autowireBean() Example:

@Component
public class PlatformEventFactory {

    @Autowired  
    private AutowireCapableBeanFactory beanFactory;

    public PlatformEvent createEvent(String eventType) {
        if (eventType.equals("deployment_activity")) {
            PlatformEvent platformEvent = new UdeployEvent();
            beanFactory.autowireBean(platformEvent);
            return platformEvent;
        }

        return null;
    }
}

beanFactory.autowireBean(platformEvent) should inject your fields and it should work fine.

There are more extended solutions with @Configuration, but they produce a lot of boilerplate code and doesn't give to much in return.

Haven't seen cleaner solution in Spring (like @AssistedInject in Guice).

Source: http://www.kubrynski.com/2013/09/injecting-spring-dependencies-into-non.html

about 4 years ago · Santiago Trujillo Relatório

0

You should annotate your bean as SCOPE_PROTOTYPE, as @ken-bekov pointed out.

To obtain an instance of prototype bean you can use injected (autowired) org.springframework.beans.factory.ObjectProvider<T>, rather than ApplicationContext. Type parameter of this provider should be UdeployEvent.
Additionally you can provide arguments for class constructor or factory method in get method. One downside of this approach is that call to get won't be statically checked.

One more way to solve your issue is trying to use Google's AutoFactory.

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda