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

145
Visualizações
Spring - register scoped bean at runtime

I am working on a Spring-based application which registers a custom scope "task". The idea is that when a new Task is started, Spring should supply task-scoped objects.

The task is instantiated in the runtime. It is supplied with some configuration in the form of a Properties object. I want to register that object with the ApplicationContext but within the task scope so that all beans within that scope can reference the configuration of that particular task.

Here is the rough idea in code:

public class MyTask extends SourceTask {
    @Override
    public void start(Map<String, String> props) {
        context = ContextProvider.getApplicationContext();
        // Initialize the scope
        ConnectorTaskScope scope = context.getBean(ConnectorTaskScope.class);
        scope.startNewTask();

        // TODO register the props object in the context

        // get an object which requires the properties and work with it
        context.getBean(SomeScopedBean.class);        
    }
}

I can't figure out how can I register a bean in the ApplicationContext that is scoped appropriately.

Thank you

Update:

Here is some more code to explain the question a bit better. SomeScopedBean should be doing something with the configuration it has bean provided with and looks something like this:

public class SomeScopedBean {
    @Autowire
    public SomeScopedBean (Properties configuration) {
        // do some work with the configuration 
    }
}

The idea of the application is that it should have multiple instances of MyTask running with different configuration and each task is its own scope. Within the scope of each task, there should be 1 instance of SomeScopedBean initialized with the task's configuration.

public class MyApplication {
    public static void main (String[] args) {
        // ...
        Properties config1 = loadConfiguration1();
        Properties config2 = loadConfiguration2();
        MyTask task1 = new MyTask();
        MyTask task2 = new MyTask();
        task1.start(config1);
        task2.start(config2);
        // ...
    }
}
about 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

If I take your last comment:

What I want is to have 1 instance of SomeScopedBean within each scope (within each MyTask), but each configured with different configuration properties (which are provided by the deployment framework when it instantiates each Task,

And especially within each MyTask and if it is limited to MyTask.

You can:

  • define SomeScopedBean as a prototype bean
  • create a factory @Configuration which will instantiate SomeScopedBean with the provided properties configuration

First the configuration:

@Configuration
public class SomeScopedBeanFactoryConfiguration {

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public SomeScopedBean create(Properties configuration) {
        return new SomeScopedBean(configuration);
    }

}

Then autowired the SomeScopedBeanFactoryConfiguration into MyTask and creates SomeScopedBean:

public class MyTask extends SourceTask {

    @Autowired
    private SomeScopedBeanFactoryConfiguration  someScopedBeanFactoryConfiguration;

    @Override
    public void start(Map<String, String> props) {
        SomeScopedBean scopedBean = someScopedBeanFactoryConfiguration.create(props);    
    }
}

Note: if SomeScopedBean must be injected in more than one bean with the task/thread scope, you could change its scope to your thread scope one eg.:

    @Bean
    @Scope("thread")
    public SomeScopedBean create(Properties configuration) {
        return new SomeScopedBean(configuration);
    }
about 4 years ago · Santiago Trujillo Relatório

0

AutowireCapableBeanFactory beanFactory = applicationContext.getAutowireCapableBeanFactory(); MyTask instance = new MyTask(); beanFactory.autowireBean(instance); beanFactory.initializeBean(instance, MyTask.class.getCanonicalName()); //for singleton I used ((ConfigurableListableBeanFactory)beanFactory).registerSingleton(MyTask.class.getCanonicalName(), instance);

In your case, you would register MyTask Proxy's singleton. The proxy can hold all of its scope-dependent instances (for example, in a map or in ThreadLocal storage) and call delegate logic to fix one of the map.

UPDATE: Actually you don't autoconnect the MyTask bean but a Proxy. The proxy wraps all the methods of MyTask. Proxy has the same interface as MyTask. Suppose you call the ProxyMyTask.do() method. The proxy intercepts the call, somehow gets the scope, say the current thread in the case of the Tread Scope example, and gets from the map (or for the thread scope from the ThreadLocal storage) the appropriate instance of MyTask. Finally, it calls the do(0 method of the found MyTask instance.

UPDATE 2: see example http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html You can easily wrap an interface. Your logic for scoping and returning the proper instance should be in the method

 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target, args); }
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