0

I'm creating pojo class and store the application.properties variable but I'm getting null values

NOTE: need to access env from my Abstract class

POJO class

package mynt.xyz.c4.pushnotif.config;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Configuration("notificationEnvironment")
@ConfigurationProperties(prefix = "app.notif")
public class NotificationEnvironment {
    private String key;
    private String url;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}

Initializing class with @autowired

public abstract class NotificationBase {

    @Autowired
    NotificationEnvironment notificationEnvironment;

    public void getEnv(){
    system.out.println(notificationEnvironment.getKey()); // null value
    }
}

concrete class that extend to my NotificationBaseClass

@Component
@Qualifier("androidNotification")
public class AndroidNotification extends NotificationBase implements Notification {

    public AndroidNotification(String message, String title, String datalink, List<String> instanceIds) {
        super(message, title, datalink, instanceIds);
    }

    AndroidNotification(){
        super();
    }

    @Override
    public void send() {
        this.getEnv();
    }
}

application.properties

app.notif.key=jkashdkjashd
app.notif.url=https/some.url
  • works fine for me, can you add, how are you testing it. – dkb Sep 02 '19 at 06:41
  • If you are accessing from `NotificationBase` class, since it is abstract class, it will not add @autowired dependencies, make it none abstract and check, and add `@Component`, this should work fine. – dkb Sep 02 '19 at 06:50
  • @dkb dont know why it's not working for me i'm stuck on this problem. using postman to test my api I got an error with java null pointer exception. – Kimbriel Oraya Sep 02 '19 at 06:50
  • @dkb I extend my NotificationBase class to my two concrete class that they are sharing same attributes I need this to be abstract and call getEnv method. do you have any other suggestion? – Kimbriel Oraya Sep 02 '19 at 06:56
  • if possible can you please add, one of the concrete class definition in question. – dkb Sep 02 '19 at 06:58
  • Autowiring will only work in spring beans. if the classes extending from `NotificationBase` aren't spring beans but managed by yourself by doing `new MyExtendedNotificationBase` autowiriung will not work. – M. Deinum Sep 02 '19 at 07:06
  • already added @dkb I eddited my code sorry for non sense void method – Kimbriel Oraya Sep 02 '19 at 07:07
  • M.Deinum my concrete classes has @Component annotation is that not counted as bean? – Kimbriel Oraya Sep 02 '19 at 07:16
  • Check this: https://stackoverflow.com/a/57752654/2987755, should work fine – dkb Sep 02 '19 at 07:20

3 Answers3

0

You can auto wire @Configuration class from @Configuration class

@Configuration class may reference the instance of any other @Configuration class using @Autowired. This works because the @Configuration classes themselves are instantiated and managed as individual Spring beans.

Ori Marko
  • 56,308
  • 23
  • 131
  • 233
0

Make your class @Component and add prefix value in @ConfigurationProperties, like this. This works for me, hope this works for you as well.

@Component
@ConfigurationProperties(prefix = "app.notif")
public class NotificationEnvironment {
    private String key;
    private String url;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

}

You can use this properties like this:

@Component
public class NotificationBase {

    private static NotificationEnvironment notificationEnvironment;

    @Autowired
    public NotificationBase(NotificationEnvironment notificationEnvironment){
        this.notificationEnvironment = notificationEnvironment;
    }

    public static void getEnv(){
        System.out.println(notificationEnvironment.getKey()); // null value
    }

}

Safwan Shaikh
  • 546
  • 2
  • 9
0

Here is the one of the concrete class definition as OP author mentioned.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ConcreteNotification extends NotificationBase {

    @Autowired
    public ConcreteNotification(NotificationEnvironment notificationEnvironment) {
        super(notificationEnvironment);
    }
}

updated NotificationBase as below

public abstract class NotificationBase {

    NotificationEnvironment notificationEnvironment;

    public NotificationBase(NotificationEnvironment notificationEnvironment) {
        this.notificationEnvironment = notificationEnvironment;
    }

    public void getEnv(){
        System.out.println(notificationEnvironment.getKey());
    }
}

The controller class I am using to get configuration values

@RestController
public class ArticleCommentController {

    @Autowired
    ConcreteNotification concreteNotification;


    @RequestMapping(value = "/health_check", method = RequestMethod.GET)
    public void getDemo() {
        concreteNotification.getEnv();
    }
}

output:

jkashdkjashd

dkb
  • 4,389
  • 4
  • 36
  • 54
  • I've still not getting my environment – Kimbriel Oraya Sep 02 '19 at 07:33
  • Then there can be some other issue related to spring config, for reference: https://github.com/dineshbhagat/spring-boot-web-jpa, used same way it is in github repo. – dkb Sep 02 '19 at 07:35
  • if possible can you share code in github, will check – dkb Sep 02 '19 at 07:36
  • I've get my property with @Autowire in CommandLineRunner run method but not working in my concrete classes – Kimbriel Oraya Sep 02 '19 at 07:40
  • I am adding it to application.properties file and able to get it from there. may be for start, add it in application.properties then go for command line argument with -D flag – dkb Sep 02 '19 at 08:09
  • I have factory class that return my concrete classes, I able to get my environment in my factory class with @Autowire too. I think because of this initialization: return new AndroidNotification(message, title, datalink, instanceIds); I think this is the cause why I cannot get my environment – Kimbriel Oraya Sep 02 '19 at 08:14
  • you need to add `public NotificationBase(NotificationEnvironment notificationEnvironment) { this.notificationEnvironment = notificationEnvironment; }` in NotificationBase.java – dkb Sep 02 '19 at 08:15
  • also `@Autowired public ConcreteNotification(NotificationEnvironment notificationEnvironment) { super(notificationEnvironment); }` in ConcreteNotification.java – dkb Sep 02 '19 at 08:16