I have a method to create a security token. The token stays alive for 5 mins.
I then use that token to perform other actions. Since it stays alive for 5 mins, I dont want to create the token on every request. Is expensive.
Instead I wish to reuse it for 4 mins then refresh the call to create a new token.
Thus thought to do it in the following manner.
@Configuration
@EnableScheduling
public class Config {
private final Authorization authorization; // this is a @Component
public AuthConfig(Authorization authorization) {
this.authorization = authorization;
}
@Scheduled(fixedDelayString = "${fixed.delay:PT4M}") // either use a value to pass in else default to 4 mins
@Bean
public String getToken() { // can't actually do this. Method needs to be void
return authorization.getToken();
}
}
Then use this String in the Component where I need the token.
Like:
@Component
public class Manager {
private final String path;
private final String token; // coming from above bean
private final RestOperations restOperations;
public Manager(
@Value("${my.path}")String path,
String token,
RestOperations restOperations) {
this.path = path;
this.token = token;
this.restOperations = restOperations;
}
public Object restCall() {
// use the token to make a rest call here.
}
}
But it turns out I actually can't use @Scheduled
to return the value.
Methods using @Scheduled
needs to be void
.
Is there way I could schedule this so that I could reuse the token and refresh it every 4 mins?
Doesn't need to use @Scheduled. Just looking for a way to do it.
CodePudding user response:
What you could do easily, to work around the return type restriction:
@Scheduled(fixedDelayString = "${fixed.delay:PT4M}")
public void updateToken() {
someTokenHolder.setToken(authorization.getToken());
}
where someTokenHolder
would be an (e.g.) singleton bean. (at the costs of replacing token
with someTokenHolder.token
).
Without a holder object/bean, we could use spring context directly, e.g. like:
@Autowired
GenericApplicationContext ctxt;
@Scheduled(fixedDelayString = "${fixed.delay:PT4M}")
public void updateToken() {
ctxt.registerBean("token", String.class, authorization.getToken());
}
(my) Best (un-over-slept) in your scenario:
Authorization
(class/object) will be "token holder", whereas the @Scheduled
job will trigger an update.
- Refactor
Authorization#getToken
to:- rename to
updateToken()
. - return
void
. - store the token to an instance variable (
token
, instead).
- rename to
- Introduce a (plain field) getter for
token
:getToken()
. - In your
Manager
don't (constructor) wire the token, butAuthorization
(singleton?), and refer toauthorization.getToken()
(where you needtoken
). - Implement the
@Scheduled
as outlined:@Scheduled(fixedDelayString = "${fixed.delay:PT4M}") public void updateToken() { authorization.updateToken(); }