Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass values from application.properties to a java abstract class?

I'm new to Java class design and need help with the following:

Example scenario: I want to pass the company name and email to the BaseEmailMessage class, and fetch these values from the application.properties file.

I also have static variables SIGN_UP_URL and PASSWORD_RESET_URL in the SignUpEmail and PasswordResetEmail classes, respectively, and I need to fetch these from the same properties file.

abstract public class BaseEmailMessage {
    // Need to fetch these from application properties
    // as they are common for all email types
    private String COMPANY_NAME;
    private String COMPANY_EMAIL;
    
    // constructor, methods, getters, and setters...
}

@Component
public class SignUpEmail extends BaseEmailMessage {

    // Need to fetch this from application properties specific to this class only
    private static final String SIGN_UP_URL;
}

@Component
public class PasswordResetEmail extends BaseEmailMessage {

    // Need to fetch this from application properties specific to this class only
    private static final String PASSWORD_RESET_URL;
}

How can I achieve this in a clean and maintainable way? Any best practices to improve the maintainability of this code?

Thanks!

I tried autowiring the Environment instance to the classes, but not sure should I move with that approach or not?

like image 410
kdeepak Avatar asked Sep 01 '25 04:09

kdeepak


1 Answers

You can use @ConfigurationProperties and constructor injection instead of manually fetching values from the environment. I think it is a maintainable way to achieve what you're asking.

Avoid using static fields because they're not easily injected by Spring.

Define your properties clearly in application.properties :

email.company-name=Example Company
[email protected]
email.signup.url=https://example.com/signup
email.passwordreset.url=https://example.com/reset-password

Define a class to load common email configuration properties:

@Component
@ConfigurationProperties(prefix = "email")
public class EmailProperties {
    private String companyName;
    private String companyEmail;
    
    private final Signup signup = new Signup();
    private final Passwordreset passwordreset = new Passwordreset();
    
    // getters and setters
    
    public static class Signup {
        private String url;
        // getters and setters
    }
    
    public static class Passwordreset {
        private String url;
        // getters and setters
    }

    // getters and setters for top-level properties
    public String getCompanyName() { return companyName; }
    public void setCompanyName(String companyName) { this.companyName = companyName; }

    public String getCompanyEmail() { return companyEmail; }
    public void setCompanyEmail(String companyEmail) { this.companyEmail = companyEmail; }

    public Signup getSignup() { return signup; }
    public Passwordreset getPasswordreset() { return passwordreset; }
}

Use constructor injection in your abstract class BaseEmailMessage:

public abstract class BaseEmailMessage {
    protected final String companyName;
    protected final String companyEmail;

    protected BaseEmailMessage(String companyName, String companyEmail) {
        this.companyName = companyName;
        this.companyEmail = companyEmail;
    }

    // methods, getters, etc.
}

Subclasses inject their specific URLs in constructors, along with the common properties:

@Component
public class SignUpEmail extends BaseEmailMessage {
    private final String signupUrl;

    public SignUpEmail(EmailProperties emailProperties) {
        super(emailProperties.getCompanyName(), emailProperties.getCompanyEmail());
        this.signupUrl = emailProperties.getSignup().getUrl();
    }

    // methods using signupUrl
    public String getSignupUrl() {
        return signupUrl;
    }
}

I think this way is maintainable because it is clear separation, easy management and constructor injection.

like image 113
jialin.zhou Avatar answered Sep 02 '25 18:09

jialin.zhou