1

I want to have a map of @Component instances of the same class. I init the instance like:

applicationContext.getBean(TorrentService.class)

TorrentService looks like this:

@Component
public class TorrentService {

    @Autowired
    private SimpMessagingTemplate template;

    @Autowired
    private TorrentRepository repository;

    private BtClient client;

    @Value("${refreshInterval}")
    private int interval;

...

All @Autowired properties are initialized, except property interval.

When I initialize instance of TorrentService using @Autowired the property interval is set correctly. It's supposed to be set to 1000 instead it's set to 0.

application.properties:

refreshInterval=1000

Is it because applicationContext.getBean is outside IoC?

What can be done?

miskohut
  • 957
  • 1
  • 14
  • 34
  • can you show the output ? and what are you expecting ? – Ryuzaki L Dec 23 '20 at 15:49
  • @Deadpool I edited the question. There's no error, only the property annotated with @ Value is not set. – miskohut Dec 23 '20 at 15:53
  • show how you are initializing `TorrentService` and how you are checking for that value ? – Ryuzaki L Dec 23 '20 at 15:55
  • I just @Autowire ApplicationContext and the call applicationContext.getBean(TorrentService.class). I check the value in debugger when a method of TorrentService is called. – miskohut Dec 23 '20 at 15:58
  • That's not why, but I'm not sure why you're getting that. Always prefer constructor injection to field injection; that will help reduce the possibility for certain injection errors like this. – chrylis -cautiouslyoptimistic- Dec 23 '20 at 16:13
  • @chrylis-cautiouslyoptimistic- could you provide an example of such an injection for this case? – miskohut Dec 23 '20 at 16:18
  • yes, could that be causing the problem? – miskohut Dec 23 '20 at 16:43
  • Lombok isn't necessarily a problem (I use it all the time in Java); just checking. For constructor injection, make all your fields final and add a constructor `TorrentService(SimpMessagingTemplate template, TorrentRepository repository, @Value("${refreshInterval}") int interval)` with appropriate implementation. (Note that you can also use `Duration` with `@Value`, which might be more convenient than a plain `int` depending on how your implementation works.) – chrylis -cautiouslyoptimistic- Dec 23 '20 at 16:46
  • Could you please check if it works after you add `@PropertySource("classpath:application.properties")` at your TorrentService class level? – Eulodos Dec 23 '20 at 18:19
  • Are you using Spring boot or not. If yes, can you provide where you have placed the application.properties file ?? it should be under /src/main/resources directory, if not, do you have already configured some class annotated with @PropertySource ? – Juan BC Dec 23 '20 at 19:33

1 Answers1

0

You should use

@Value("#{refreshInterval}")
codiallo
  • 173
  • 4