14

I need change properties in my application at runtime. For example I have a service which send a e-mail with resset password. Request is valid 12 hours. But I want to change this time to 24 or more at runtime. I need to give the opportunity to this action for admin.

My property file has

hours.expired=12

My service

private int hoursExpiredPassword;

public void setHoursExpiredPassword(int hoursExpiredPassword) {
    this.hoursExpiredPassword = hoursExpiredPassword;
}

@Override
public ERequests checkRequest(String number, Date date) {
    PasswordResetRequest findedObject = passwordResetRequestDao.getObjectByElement(PasswordResetRequest.class, "requestId", number);
    if (findedObject == null){
        return ERequests.BAD_REQUEST;
    }else{
        long result = getDateDiff(findedObject.getRequestDate(),date,TimeUnit.HOURS);
        if(result >= hoursExpiredPassword){
            return ERequests.EXPIRED_REQUEST;
        }
    }
    return ERequests.CORRECT_REQUEST;
}

my spring xml configuration

<bean id="passwordResetRequestService" class="pl.lublin.example.services.servicesDAO.PasswordResetRequestService">
    <property name="passwordResetRequestDao" ref="passwordResetRequestDao"></property>
    <property name="hoursExpiredPassword" value="${hours.expired}"></property>
</bean>

Could I change this value in someway at runtime?

Tom
  • 301
  • 1
  • 3
  • 9

2 Answers2

13

Just move away from xml configuration its almost 2017.

@Service
public class PasswordResetRequestService {

@Value("${hours.expired:12}") 
private int hoursExpiredPassword;

@Autowired
private PasswordResetRequestDao passwordResetRequestDao;

public void setHoursExpiredPassword(int hoursExpiredPassword) {
    this.hoursExpiredPassword = hoursExpiredPassword;
}


@Override
public ERequests checkRequest(String number, Date date) {
    PasswordResetRequest findedObject = passwordResetRequestDao.getObjectByElement(PasswordResetRequest.class, "requestId", number);
    if (findedObject == null){
        return ERequests.BAD_REQUEST;
    }else{
        long result = getDateDiff(findedObject.getRequestDate(),date,TimeUnit.HOURS);
        if(result >= hoursExpiredPassword){
            return ERequests.EXPIRED_REQUEST;
        }
    }
    return ERequests.CORRECT_REQUEST;
   }

}

With @Value you are pulling hours.expired value from properties file, if there is no value default will be 12. You can also call setHoursExpired at runtime and set new value and expose that functionality to your admins.

This is convenient for one time actions. If you want your admins to permanently change password expiration time i would instead persist hours.expired value in mysql or whatver db you are using.

EDIT : answering to perfectly valid @matt remark . If that is the case and moving to Java confing is not an option. For custom behavior you can just autowire your XML-defined beans in your service and perform whatever logic you want to.

@Autowired
private pl.lublin.zeto.zetoRA.services.servicesDAO.PasswordResetRequestService passwordResetRequestService;

EDIT: 2020

Defacto standard way of doing this in 2020 is setup of Cloud Config server backed by a git repository. Example:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/spring-cloud-samples/config-repo

as explained here : https://cloud.spring.io/spring-cloud-config/reference/html/

You need standalone spring config app which will be used by all the client apps. The most robust solution is to back spring config server by git repository. By doing this we have version control on production settings and avoid the risk of changing something then forgetting what the previous value was etc.

Captain Man
  • 6,997
  • 6
  • 48
  • 74
SeaBiscuit
  • 2,553
  • 4
  • 25
  • 40
  • 2
    Good answer, perfectly valid for non-XML configuration. Just consider that some projects are built fully upon XML, probably his, too. – Jan B. Aug 04 '16 at 08:59
  • 29
    this doesn't answer the question – jucardi Oct 07 '16 at 04:00
  • I know it is holywar - xml or java config or groovy but why xml is bad if it works well? – Vladyslav K Jan 25 '17 at 14:15
  • 6
    +1 for the XML rant. XML is bad because it has no type or signature checking or code completion, is fragile when updating dependencies, is opaque in it's functionality, is less testable than code, and doesn't have built in IDE documentation support. – Max Mumford Aug 04 '17 at 18:02
  • Can the config-parameter in a config file be updated after Running the script? (for the purpose to refer in the next runtime) – hirosht Sep 01 '17 at 08:30
  • this doesn't answer the question. how can the change be on runtime without application restart? – ps138 Nov 05 '20 at 13:17
  • how is this the "correct answer" when it does not provide the answer to it. It provides a work around, if you have a small project and changing those config is an option – P. Waksman Jan 17 '23 at 10:24
-1

I have to use XML configuration. Our project is based on it. Finally I need to get all configuration values from db. The simplest solution is used service for configuration and always invoke configuration state from db.

configurationService.findAllConfigurations().get("hours.expired")

this return value what is stored in db.

But I think there is better solution.

Tom
  • 301
  • 1
  • 3
  • 9
  • I Usually create dedicated service for retrieving configuration from database. `@Component public class MyProperties{ private int hoursExpiredPassword; @PostConstruct public void init() throws Exception { List configurations = configurationService.findAllConfigurations(); // set all your configurations } ` – SeaBiscuit Aug 04 '16 at 10:24
  • This doesn't answer the question either. – ssimm Feb 13 '22 at 19:18