It happens because to process both annotations MAGIC is used.
I suppose there are several things happens:
UserServiceImpl
is created.
@Scheduled
annotation is processed and reference to bean is stored to invoke it at appropriate time.
@Transactional
annotation is processed. It create proxy which store reference to original bean. Original bean is replaced to proxy in application context.
If step 2 and 3 passed in different order then you had no problem.
I don't know how to control order in which annotation is processed. I don't even sure it is possible at all.
There is basically two solution.
- Use different kind of magic to process
@Transaction
. Default way is to create proxy object, but it is possible to instruct Spring
to instrument current class.
- Split this to two class each of them will have method with only one annotation.
Example:
@Service
public class UserServiceImpl implements UserService {
@Override
@Transactional
public void doSomething() {
}
}
@Service
public class UserServiceScheduler {
@Inject
private UserService service;
@Scheduled(fixedRateString = "${somestring}",initialDelayString = "${anotherstring}")
public void doSomething() {
service.doSomething();
}
}
I'm personally recommend second approach.