1

I have the following code:

@Component public class MainBean { @Autowired private MyTask myTask @Autowired private TaskScheduler taskScheduler public void start() { String str = "Print something to console"; //somehow call constructor and pass str argument?? taskScheduler.execute(myTask); } } @Component public class MyTask implements Runnable { private String str; @Autowired public MyTask(String str) { this.str = str; } @Override public void run() { System.out.println(str); } } 

I want to call MyTask and pass the str argument to the constructor. How can I do this? I cant find any good examples anywhere.

0

3 Answers 3

1

If I understand correctly what you are trying to do, a good solution would be the following:

@Component public class MainBean { @Autowired private MyTaskFactory myTaskFactory @Autowired private TaskScheduler taskScheduler public void start() { String str = "Print something to console"; taskScheduler.execute(myTaskFactory.getTask(str)); } } public class MyTaskFactory { public MyTask getTask(String str) { return new MyTask(str); } } @Configuration public class MyTaskFactoryConfig { @Bean public MyTaskFactory myTaskFactory() { return new MyTaskFactory(); } } 

Note that MyTask will then be changed to:

public class MyTask implements Runnable { private String str; public MyTask(String str) { this.str = str; } @Override public void run() { System.out.println(str); } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Looks like a nice solution but what if I would want to inject an @Autowired dependency in MyTask?
That case is easily dealt with, by injecting the dependency into MyTaskFactoryConfig, then passed to the MyTaskFactory using the factory's constructor, and then passed to MyTask using it's constructor. Is it clear or do you want me to update the answer with some code?
0

As seen from annotations, you've configured MyTask to be Spring managed. Also, str property is Spring managed, it should be injected by Spring to MyTask.

So, whenever you need MyTask instance, you don't create it yourself.

You @Autowire wherever you need.

public class ClassThatNeedsMyTaskInstances{ @Autowired MyTask myTask; } 

But beware that by default, MyTask will be a singleton, so you may want to change its scope to prototype.

But this may be a good case where you don't let Spring manage MyTasks lifecycle. Instead you manage it yourself by creating instances using new, or factory

1 Comment

Making just MyTask a prototype won't do any good if MainBean is a singleton. Lifecycle mismatches can be handled by lookup methods, but they seem to have fallen out of favor with annotation-driven configuration.
0

The following examples are for injecting the string from and XML and a Java-based configuration:

XML

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="MyTaskConstructor" class="java.lang.String"> <constructor-arg type="char[]" value="My value"></constructor-arg> </bean> <bean id="myTask" class="com.package.MyTask"> <constructor-arg ref="MyTaskConstructor"/> </bean> </beans> 

Java-based

@Configuration public class MyTaskConfig { @Bean public String getMyTaskConstructor() { return "My value"; } @Bean public MyTask myTask() { return new MyTask(getMyTaskConstructor()); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.