Philippe Gioseffi
Philippe Gioseffi

Reputation: 1658

Is it possible to have a constant valued through a Spring Service?

We have a web service that one of its parameters is called origin and this origin is always validated against a code in the database.

For each one of our services I have to validate this code. This code does not change so I want to keep it in a constant, but I still have to validate it to prevent clients from sending a wrong code.

Basically what I want is this:

@Service
public class Service {

    @Autowired
    private LogBS logBS;

    // I know this cannot be used in a static context.
    public static final Long CODE = this.logBS.retrieveLogWebServiceCode("webServiceName");

    public void validateOriginCode(final Long origin) {
        if (!origin.equals(CODE)) {
            throw new ServiceException("Wrong origin code!");
       }
   }
}

I know something similar can be done with Spring caching, but is it possible to do it with a constant?

Upvotes: 1

Views: 1249

Answers (2)

Aritz
Aritz

Reputation: 31679

I would rather go with this:

@Service
public class CodeValidatorService {

    private LogBS logBS;

    private Long CODE;

    @Autowired
    public CodeValidatorService(LogBS logBS){
        this.logBS = logBS;
        CODE = this.logBS.retrieveLogWebServiceCode("webServiceName");
        if (CODE == null){
            throw new ServiceException("Code cannot be read from DB!");
        }
    }

    public void validateOriginCode(final Long origin) {
        if (!origin.equals(CODE)) {
            throw new ServiceException("Wrong origin code!");
       }
   }
}

Just as a code review, I prefer injecting dependencies in the constructor rather than using @Autowired in the field directly, it makes the service testable. You could also try to read the code in a @PostConstruct method, but I think it's better to do it in the constructor so you always have the service in a ready-to-go state.

For using it in the rest of your services, inject the CodeValidatorService instance on them:

@Service
public class OtherService {

    private CodeValidatorService codeValidatorService;

    @Autowired
    public OtherService(CodeValidatorService codeValidatorService){
        this.codeValidatorService = codeValidatorService;
    }

    public void performAction(final Long origin) {
        codeValidatorService.validateOriginCode(origin);
        //do the rest of your logic here
   }
}

See also:

Upvotes: 2

yaswanth
yaswanth

Reputation: 2477

You can have a constantsProvider class

@Component
public class ConstantsProvider {

    @Autowired
    private LogBS logBS;

    private String CODE;

    @PostConstruct
    public void init() {
        CODE = this.logBS.retrieveLogWebServiceCode("webServiceName");
    }

    public String getCode() {
        return CODE;
    }
}

Add this snippet of code to Service class

@Autowired
private ConstantsProvider constantsProvider;

You can use constantsProvider.getCode() in your services. This way CODE is going to be immutable and not defined in a static context.

Note: If you have more constants similar to this, there is a better way to define the ConstantsProvider class. If there is only one, I would stick to the above implementation.

Edit 1:

If you need it in all the service classes, make the constantsProvider a spring bean and initialize the CODE there itself. Updated the answer

Upvotes: 1

Related Questions