Burton
Burton

Reputation: 923

What is the best way to set this class's member variable with a value from a .properties file?

I have several entity classes (using Spring) that also have "helper" classes associated with them that offer additional functionality. A very simplified example:

public class Contact {

    private Integer contactId;
    private String name;
    private int age;

    // Provide access to helper class
    @Transient
    public ContactHelper getContactHelper() {
        return new ContactHelper(this);
    }

    // Getters/Setters omitted
}

public class ContactHelper {

    private static String contactUrlPattern = "http://localhost/GetContact.action?contactId=[id]";

    private Contact contact;
    public ContactHelper(Contact contact) {
        this.contact = contact;
    }

    public String getContactLink() {
        return  contactUrlPattern.replace("[ID]", this.contact.getContactId());
    }

    public void setContactUrlPattern(String str) {
        contactUrlPattern = str;
    }
}

This setup provides a very convenient pattern especially when displaying values. For example, I can now write:

<a href="${contact.contactHelper.contactLink}">${contact.name}</a>

The issue now is I would like to set the contactUrlPattern with a different value from a "production" properties file (change 'localhost' to 'example.com'). Normally I would inject a value using Spring, but since this pattern create a new ContactHelper each time, it is not a part of the Spring Context.

What is the best way to go about setting this variable? I could possibly set it after the ApplicationContext is initialized in a listener since the variable is static. I would have to set about 10-15 different "helpers" and variables -- or is that wreak of code smell?

Upvotes: 1

Views: 289

Answers (3)

Andreas
Andreas

Reputation: 159096

It depends on where the code is used. If the code is executed as part of the web request, i.e. the Controller action handler method is on the call stack, then you can access the ApplicationContext, and query the Spring application attributes, which can specify different values depending on Environment.

public class ContactHelper {

    private String contactUrlPattern;
    private Contact contact;

    public ContactHelper(Contact contact) {
        this.contact = contact;

        // Get contactUrlPattern from application properties
        RequestAttributes attrs = RequestContextHolder.currentRequestAttributes();
        ApplicationContext appCtx = (ApplicationContext) attrs.getAttribute(DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE, RequestAttributes.SCOPE_REQUEST);
        Environment env = appCtx.getEnvironment();
        this.contactUrlPattern = env.getRequiredProperty("contactUrlPattern");
    }

See also: Externalized Configuration
See also: Properties and Configuration

Upvotes: 0

Burton
Burton

Reputation: 923

Thanks for your response Sanjeev. I think I've found a solution that makes sense... I am going to use the Spring @PostConstruct annotation in a class that holds all my application properties after the context is loaded.

@Component
public class MyAppProperties {

    private String clientActivitiesUrlString;

    @PostConstruct
    public void init() {
        ContactHelper.setClientActivitiesUrlString(this.getClientActivitiesUrlString());
    }
    // Getters/Setters
}

Upvotes: 1

Sanjeev Dhiman
Sanjeev Dhiman

Reputation: 1199

If I understood correctly then it is your application that would need to know what Environment it is running in. You can do it various ways, either by passing -D property or setting up 'environment' (so that System.getEnv would give you correct value), and you would have to maintain different properties file based on the env (or at least different property names, for example - url_dev, url_test or url_prod).

You may find this link helpful - https://examples.javacodegeeks.com/enterprise-java/spring/load-environment-configurations-and-properties-with-spring-example/

Upvotes: 0

Related Questions