๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Back-end ๋ฐ๋ธŒ์ฝ”์Šค/week 03 - 05 TIL (Spring)

[TIL] 221103 - SpringBoot Part1 - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†์„ฑ ๊ด€๋ฆฌ

by young-ji 2022. 11. 6.

SpringBoot Part1 (4) 

 

1. Enviroment profile

ApplicationContext๋Š” EnvironmentCapable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ƒ์†๋ฐ›์œผ๋ฉฐ getEnvironment() ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

profile์— ๋”ฐ๋ผ ํ™˜๊ฒฝ์ด ๋ฐ”๋€Œ๊ณ  ๊ทธ์— ๋”ฐ๋ผ properties๊ฐ€ ๋ฐ”๋€๋‹ค.

 

properties

: ๋‹ค์–‘ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์†์„ฑ์„ property๋กœ ์ •์˜ํ•˜๊ณ  ์„ค์ •ํ•œ๋‹ค. ๋‹ค์–‘ํ•œ ๋ฐฉ์‹์œผ๋กœ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

resources > application.properties

: springboot์—์„œ default๋กœ ์‚ฌ์šฉํ•˜๋Š” property ํŒŒ์ผ

: key/value ํ˜•์‹์œผ๋กœ ์ž‘์„ฑ

version = v1.0.0
kdt.version = v1.0.0
kdt.support-vendors = a,b,c,d,e,f,g
kdt.minimum-order-amount = 1

 

properties ํŒŒ์ผ ์ฝ์–ด์˜ค๊ธฐ

  • Configuration class์— PropertySource ์ถ”๊ฐ€
@Configuration
@ComponentScan
@PropertySource("application.properties")
public class AppConfiguration {

}
public static void main(String[] args) {

      var applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);

      var environment = applicationContext.getEnvironment();
      var version = environment.getProperty("kdt.version");
      var minimunOrderAmount = environment.getProperty("kdt.minimum-order-amount", Integer.class);
      var supportVendeor = environment.getProperty("kdt.supportVendors", List.class);
}

 

  • Value ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์‚ฌ์šฉ
@Component
public class OrderProperties implements InitializingBean {

    @Value("v.1.1.1") // ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ๊ฐ’์„ ์ฃผ์ž…
    private String version;

    @Value("${kdt.minimum-order-amount:8}") //properties ๊ฐ’ ์ฃผ์ž… : default๊ฐ’
    private String minimumOrderAmount;

    private List<String> supportVendors;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(MessageFormat.format("version -> {0}", version));
        System.out.println(MessageFormat.format("minimumOrderAmount -> {0}", minimumOrderAmount));
        System.out.println(MessageFormat.format("supportVendors -> {0}", supportVendors));
    }
}

์‹œ์Šคํ…œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋„ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋™์ผํ•œ ์ด๋ฆ„์ผ ๊ฒฝ์šฐ ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค.

 

 

  • ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” class ๋งŒ๋“ค๊ธฐ

ํ•„์š”ํ•œ ์‹œ์Šคํ…œ ์†์„ฑ๋“ค์„ ์ œ๊ณตํ•ด์ฃผ๋Š” ๋ชฉ์ ์˜ class๋ฅผ ๋งŒ๋“ค์–ด property๋ฅผ ์ •์˜ํ•œ๋‹ค.

@Component
@PropertySource("version.properties")
public class VersionProvider {
    private final String version;

    public VersionProvider(@Value("${version:v0.0.0}") String version) {
        this.version = version;
        System.out.println(version);
    }
}

 

 

2. YAML๋กœ ํ”„๋กœํผํ‹ฐ์ž‘์„ฑ

YAML

: ๋˜ ๋‹ค๋ฅธ ๋งˆํฌ์—… ์–ธ์–ด. ๋ฐ์ดํ„ฐ ์ค‘์‹ฌ

: ์˜ค๋Š˜๋‚  XML, JSON์ด ๋ฐ์ดํ„ฐ ์ง๋ ฌํ™”์— ์ฃผ๋กœ ์“ฐ์ด๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด์„œ, ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด YAML์„ ‘๊ฐ€๋ฒผ์šด ๋งˆํฌ์—… ์–ธ์–ด’๋กœ ์‚ฌ์šฉํ•˜๋ ค ํ•œ๋‹ค.

YAML ๋ฌธ๋ฒ•

kdt:
  version: "v1.0"
  minimum-order-amount: 1
  support-vendors:
    - a
    - b
    - c
    - d
  description: |
    line 1 hello world
    line 2 xxx
    line 3

 

Spring ํ”„๋ ˆ์ž„์›Œํฌ๋Š” PropertySource ์—์„œ YAML์„ ์ง€์›ํ•˜์ง€์•Š์•„ PropertySourceFactory๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค.

public class YamlPropertiesFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        var yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
        yamlPropertiesFactoryBean.setResources(resource.getResource());

        var properties = yamlPropertiesFactoryBean.getObject();
        return new PropertiesPropertySource(resource.getResource().getFilename(), properties);

    }
}

 

yaml์—์„œ List๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์œ„ํ•ด SpringBoot์—์„œ ์ œ๊ณตํ•ด์ฃผ๋Š” ConfigurationProperties๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค.

@Configuration
@ComponentScan
@PropertySource(value = "application.yaml", factory = YamlPropertiesFactory.class)
@EnableConfigurationProperties // SpringBoot์— ConfigurationProperties๋ฅผ ์“ฐ๊ฒ ๋‹ค.
public class AppConfiguration {

}
@Configuration
@ConfigurationProperties(prefix = "kdt") // SpringBoot ์–ด๋…ธํ…Œ์ด
public class OrderProperties implements InitializingBean {

    private String version;

    private int minimumOrderAmount;

    private List<String> supportVendors;
    private String description;

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(MessageFormat.format("version -> {0}", version));
        System.out.println(MessageFormat.format("minimumOrderAmount -> {0}", minimumOrderAmount));
        System.out.println(MessageFormat.format("supportVendors -> {0}", supportVendors));
        System.out.println(MessageFormat.format("description -> {0}", description));
    }

		// ๊ฐ’์„ ์ฃผ์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ setter ํ•„์š”
    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }

    public int getMinimumOrderAmount() {
        return minimumOrderAmount;
    }

    public void setMinimumOrderAmount(int minimumOrderAmount) {
        this.minimumOrderAmount = minimumOrderAmount;
    }

    public List<String> getSupportVendors() {
        return supportVendors;
    }

    public void setSupportVendors(List<String> supportVendors) {
        this.supportVendors = supportVendors;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
public static void main(String[] args) {

      var applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);

      var orderProperties = applicationContext.getBean(OrderProperties.class);
      System.out.println("test -- "+orderProperties.getVersion());
}

์–ด๋ ต๋‹ค.

 

3. profile

: ํŠน์ •ํ•œ ์†์„ฑ์œผ๋กœ ๊ทธ๋ฃนํ™”

: ์„ค์ •์ด๋‚˜ Bean๋“ค์„ ๊ทธ๋ฃนํ™”ํ•ด์„œ ํ•˜๋‚˜์˜ profile๋กœ ์ •์˜ํ•˜๊ณ  ์—ฌ๋Ÿฌ๊ฐœ์˜ profile ์ค‘ ์›ํ•˜๋Š” profile๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

Profile ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด ์ด๋ฆ„์„ ์„ค์ •

@Repository
@Profile("dev")
public class JdbcVoucherRepository implements VoucherRepository{
    @Override
    public Optional<Voucher> findById(UUID voucherId) {
        return Optional.empty();
    }

    @Override
    public Voucher insert(Voucher voucher) {
        return null;
    }
}
public static void main(String[] args) {

      var applicationContext = new AnnotationConfigApplicationContext();
      applicationContext.register(AppConfiguration.class);
      var environment = applicationContext.getEnvironment();
      environment.setActiveProfiles("local"); //profile ์„ ํƒ
      applicationContext.refresh(); //profile์ด ์žฌ๋Œ€๋กœ ์ ์šฉ๋  ์ˆ˜ ์žˆ๊ฒŒ refresh
}

 

 

YAML ํŒŒ์ผ์—๋„ profile ์ •์˜ ๊ฐ€๋Šฅ - springboot ๊ธฐ๋Šฅ

---
spring.config.activate.on-profile : local
kdt:
  version: "v1.0"
  minimum-order-amount: 1
  support-vendors:
    - a
    - b
    - c
    - d
  description: |
    line 1 hello world
    line 2 xxx
    line 3
---
spring.config.activate.on-profile : dev
kdt:
  version: "v1.0-dev"
  minimum-order-amount: 1
  support-vendors:
    - a
    - b
    - c
    - d
  description: |
    line 1 hello world
    line 2 dev
    line 3 dev
---

: ํ•˜๋‚˜์˜ ํŒŒ์ผ์—์„œ ์—ฌ๋Ÿฌ profile์„ ๊ตฌ์„ฑํ•  ์ˆ˜๋„ ์žˆ๊ณ  ์—ฌ๋Ÿฌ๊ฐœ์˜ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์„œ ์ ์šฉ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

 

@SpringBootApplicateion : ์‹คํ–‰ ๋Ÿฐ์ฒ˜๊ฐ€ ๋‹ค๋ฅด๋‹ค.

@SpringBootApplication
public class KdtApplication {

    public static void main(String[] args) {

        var springApplication = new SpringApplication(KdtApplication.class);
        springApplication.setAdditionalProfiles("local");
        var applicationContext = springApplication.run(args);

        //var applicationContext = SpringApplication.run(KdtApplication.class, args);
    }

}

: run/debug ๊ตฌ์„ฑ ํŒŒ์ผ์—์„œ Activate profiles ํ˜น์€ arguments๋กœ profile์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

4. Resource

Spring์€ ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค(์ด๋ฏธ์ง€, ํ…Œ์ŠคํŠธ, key ํŒŒ์ผ ๋“ฑ)๋ฅผ ํ•˜๋‚˜์˜ API๋กœ ์ฝ์–ด์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

→ Resource / ResourceLoader ์ธํ„ฐํŽ˜์ด์Šค

: ResourceLoader๋ฅผ ํ†ตํ•ด Resource๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

: ๋ชจ๋“  ApplicationContext๊ฐ€ ResourceLoader๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค. (Resource ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. )

 

public static void main(String[] args) throws Exception{

      var applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);

      var resource = applicationContext.getResource("application.yaml"); //working directory ๊ธฐ์ค€, classpath ๊ฐ€ ๊ธฐ๋ณธ๊ฐ’
      var resource2 = applicationContext.getResource("file:test/sample.txt"); //
      var resource3 = applicationContext.getResource("<https://stackoverflow.com/>");

      System.out.println(resource.getClass().getCanonicalName());

      var file = resource2.getFile();
      var strings = Files.readAllLines(file.toPath());
      System.out.println(strings.stream().reduce("",(a,b)->a+"\\n"+b));

      var readableByChannel = Channels.newChannel(resource3.getURL().openStream());
      var bufferedReader = new BufferedReader(Channels.newReader(readableByChannel, StandardCharsets.UTF_8));
      var contents = bufferedReader.lines().collect(Collectors.joining("\\n"));
      System.out.println(contents);
}

 

 


Daliy Mssion

  • ๊ณ ๊ฐ ๋ธ”๋ž™ ๋ฆฌ์ŠคํŠธ ๋ช…๋‹จ ์ž‘์„ฑ
    • customer_blacklist.csv ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. → parsing
  • YAML ํ”„๋ผํผํ‹ฐ๋ฅผ ๋งŒ๋“ค๊ณ  ์–ด๋–ค ์„ค์ •์„ ๋งŒ๋“ค์ˆ˜ ์žˆ์„์ง€ ๊ณ ๋ฏผํ•ด๋ณด๊ธฐ
  • ๋ฐ”์ด์ฒ˜๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๋ ˆํฌ๋Š” ๊ฐœ๋ฐœ ํ”„๋กœํŒŒ์ผ์—์„œ๋งŒ ๋™์ž‘ํ•˜๊ฒŒ ํ•ด๋ณด๊ธฐ

๋Œ“๊ธ€