Anjani Kumar
Anjani Kumar

Reputation: 21

Setter Injection Using Java Configuration

I have a Runnable (i.e. a Class Implementing Runnable). There is one SpringBean where i am using this Runnable by calling its Contstructor. I want to make this Runnable a Spring Bean.

Ex.

Class RunTest implements Runnable {

    Object object;

    public RunTest(Object a){
        this.object=a;
    }

    public void run() {
        //using attributes of a 
    }

}

Now I have a Spring Bean

@Named
Class TestSpringBean {

    public void someMethod(){
        Object a;
        new RunTest(a)
    }

}

Can i inject RunTestClass inside TestSpringBean and use.

Upvotes: 2

Views: 407

Answers (2)

Andrew
Andrew

Reputation: 49606

Mark the class RunTest as a @Component, inject its instance into the class TestSpringBean, and complete the configuration in the method someMethod*:

@Component
class RunTest implements Runnable {
    public RunTest() {}
}

class TestSpringBean {

    @Autowired
    private RunTest runnable;

    public void someMethod() {
        ...
        runnable.set(a);
    }

}

*Note that you are supposed to get an already-configured component, so no other configurations are required. It's a singleton instance, so the changes here will be reflected in other places as well.

In other words, singletons should remain stateless. That's why this simple solution should be revised by either finding a way to obtain a complete object or excluding that object from the task class.

**You might change the scope to "prototype", but Spring still couldn't provide a fully-configured instance. It raises a question: should Spring manage this class at all?

***As pointed out by @lucumt, make sure that the class is visible for the component scan mechanism.

Upvotes: 1

Mohammadreza  Alagheband
Mohammadreza Alagheband

Reputation: 2230

Description:

TaskExecutor is as an abstraction for dealing with executors that is introduced since Spring 2.0.Spring’s TaskExecutor interface can be considered as identical to the java.util.concurrent.Executor interface. There are also a number of built-in implementations of TaskExecutor included with the Spring distribution. read them here : https://docs.spring.io/spring/docs/2.5.x/reference/scheduling.html


How To:

1. Define a TaskExecutor configuration to your spring application:

@Configuration
public class MultiThreadConfig {

    @Bean
    public TaskExecutor threadPoolTaskExecutor() {

        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(5);
        executor.setThreadNamePrefix("DEFAULT");
        executor.initialize();

        return executor;
    }

}

2. Define you runnable as Prototype

  • Make sure you change Object to your required custom type

    @Component
    @Scope("prototype")
    public class RunTest implements Runnable {
    
        @Autowired
        ChangeObjectToYourNeed object ;
    
        public RunTest(ChangeObjectToYourNeed a) {
            this.object = a;
        } 
    
        @Override
        public void run() {
            // your code
        }
    }
    

3. Inject the executor to your services in order to execute runnable instances:

@Service
public class AsynService {

    @Autowired
    private TaskExecutor taskExecutor;

    @Autowired
    private ApplicationContext applicationContext;

    public void executeAsync() {
        RunTest runTest = applicationContext.getBean(MyThread.class);
        taskExecutor.execute(runTest);
    }

}

Upvotes: 0

Related Questions