찾다
Javajava지도 시간Spring 예약 작업에 대한 사용 지침

Spring 예약 작업에 대한 사용 지침

Jun 30, 2017 am 10:37 AM
spring사용타이밍

1. 분류

  • 구현 기술 측면에서 보면 현재 크게 3가지 기술이 있습니다.

  1. Java 고유의 ​​java.util.Timer 클래스로, 이 클래스를 사용하면 java.util.TimerTask 작업을 예약할 수 있습니다. 이 방법을 사용하면 프로그램이 특정 빈도로 실행될 수 있지만 지정된 시간에는 실행되지 않습니다.

  2. 특정 시간이나 특정 빈도로 프로그램을 실행할 수 있는 비교적 강력한 스케줄러인 Quartz를 사용하세요. 구성이 약간 복잡합니다.

  3. Spring 3.0 이상에 포함된 작업은 경량 Quartz라고 볼 수 있으며 Quartz보다 사용하기가 훨씬 간단합니다.

  • 잡 클래스의 상속 방법은 두 가지 범주로 나눌 수 있습니다.

  1. 잡 클래스는 상속이 필요한 Quartz와 같은 특정 직업 클래스 기본 클래스에서 상속해야 합니다. org.springframework.scheduling .quartz.QuartzJobBean에서 java.util.Timer는 java.util.TimerTask에서 상속해야 합니다.

  2. 작업 클래스는 일반 Java 클래스이므로 기본 클래스에서 상속할 필요가 없습니다.

참고: 저는 개인적으로 두 번째 방법을 사용하는 것을 권장합니다. 모든 클래스가 공통 클래스이고 미리 다르게 취급할 필요가 없기 때문입니다.

  • 작업 스케줄링의 트리거 타이밍 관점에서 보면 주로 작업에 사용되는 트리거는 다음과 같습니다. 주로 다음 두 가지 유형이 있습니다. 트리거는 다음과 같습니다: org.springframework.scheduling.quartz.SimpleTriggerBean
    은 지정된 시간마다 한 번씩 트리거됩니다. Quartz의 해당 스케줄러는 다음과 같습니다: org.springframework.scheduling.quartz.CronTriggerBean
  1. 참고: 각 작업에서는 사용할 수 없습니다. 예를 들어, java.util.TimerTask 작업은 첫 번째 트리거만 사용할 수 있습니다. Quartz와 Spring 작업 모두 이 두 가지 트리거 조건을 지원할 수 있습니다.
  2. 2. 사용방법

  3. 쿼츠, 스프링 작업 등 각 작업 스케줄링 도구의 사용법을 자세히 소개합니다.

Quartz

첫 번째 유형인 작업 클래스는 특정 기본 클래스인 org.springframework.scheduling.quartz.QuartzJobBean에서 상속됩니다.

1단계: 작업 클래스 정의

Java 코드

Spring 예약 작업에 대한 사용 지침import org.quartz.JobExecutionContext
  1. org.quartz.JobExecutionException 가져오기

  2. import org.springframework.scheduling.quartz.QuartzJobBean;

  3. public class Job1

    QuartzJobBean {
  4. private int 시간 초과;

  5. 비공개
  6. int 시간 초과) {

  7. this.timeout = 시간 초과

  8. }

    /**
  9. * 예약할 특정 작업
  10. */

  11. @오버라이드

  12. protected

    void executionInternal(JobExecutionContext context)

  13. t hrows JobExecutionException {

  14. System.out.println(
  15. "예약된 작업이 실행 중입니다...")

  16. }
  17. }

  18. 2단계: 스프링 구성 파일에서 작업 클래스 JobDetailBean

  19. Xml 코드 구성

    1. bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean"> 속성 name="jobClass" value=

      "com.gy.Job1"
    2. />
    3. property name="jobDataAsMap" >

    4. map>

    5. entry key="timeout" value=

      "0"
    6. />
    7. map>

    8. property>

    9. 설명: org.springframework.scheduling.quartz.JobDetailBean에는 두 가지 속성이 있습니다. jobClass 속성은 Java 코드에서 정의한 작업 클래스이고, jobDataAsMap 속성은 작업 클래스에 주입되어야 하는 속성 값입니다. 3단계: 작업 예약의 트리거 방법(트리거) 구성

    10. Quartz에는 두 가지 작업 트리거, 즉
    11. org.springframework.scheduling.quartz.SimpleTriggerBeanorg.springframework.scheduling이 있습니다. 첫 번째 SimpleTriggerBean은 30분마다 한 번씩 실행되는 것과 같이 특정 빈도의 작업 호출만 지원합니다. 구성 방법은 다음과 같습니다.

Xml 코드

bean

id=

"simpleTrigger"

class=

"org.springframework.scheduling .quartz.SimpleTriggerBean"

>

Spring 예약 작업에 대한 사용 지침
    property

    name="jobDetail" ref="job1" /> < ;property

    name="startDelay"
  1. value=

    "0" /> property name="repeatInterval" value="2000" />

  2. bean> 두 번째 유형의 CronTriggerBean은 매일 12시에 한 번 실행하는 것과 같이 지정된 시간에 한 번 실행을 지원합니다.

    구성 방법은 다음과 같습니다.
  3. Xml 코드

    1. bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> 속성 name="jobDetail" ref=

      "job1"
    2. />
    3. > < ;property name=

      "cronExpression"
    4. value=
    5. "0 0 12 * * ?"

      />

    6. > cronExpression 표현식의 구문은 부록을 참조하세요.

    7. 4단계: 스케줄링 팩토리 구성
    8. Xml 코드

bean class=

"org.springframework.scheduling.quartz.SchedulerFactoryBean" >

Spring 예약 작업에 대한 사용 지침
  1. 속성 name="triggers"> ref
  2. bean=
  3. "cronTrigger"

    />

    list
  4. >
  5. prop 어티

    >
  6. bean>

  7. 설명: 이 매개변수는 이전에 구성된 트리거의 이름을 지정합니다. 5단계: 애플리케이션을 시작하고 프로젝트를 tomcat이나 다른 컨테이너에 배포하세요.

  8. 둘째, 직업 클래스는 특정 기본 클래스를 상속받지 않습니다. Spring은 두 가지 클래스 덕분에 이 메서드를 지원할 수 있습니다: org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean

    org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean
  9. 이 두 클래스는 각각 Spring에서 지원하는 두 가지 유형에 해당합니다. 작업 스케줄링을 구현하는 방법으로는 위에서 언급한 Java와 함께 제공되는 타이머 작업 메서드와 Quartz 메서드가 있습니다. 여기서는 MethodInvokingJobDetailFactoryBean의 사용법에 대해서만 씁니다. 이 클래스를 사용하면 작업 클래스가 더 이상 어떤 클래스에서도 상속할 필요가 없으며 일반적인 pojo라는 점입니다.

    1단계: 작업 클래스 작성

    Java 코드

public class Job2 {

public

void doJob2 () {

시스템 .out.println(

"QuartzJobBean 메서드 상속 안 함 - 예약 진행 중...");

}
Spring 예약 작업에 대한 사용 지침
}
  1. 이것은 일반적인 클래스임을 알 수 있습니다. 방법이 있습니다. 2단계: 직업 클래스 구성

  2. Xml 코드

    1. bean id="job2"

    2. class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"&g

    3. < ;property name="targetObject">

    4. bean class="com.gy.Job2" />

    5. property>

    6. property name="targetMethod" value="doJob2" />
    7. property name="concurrent" value="false" /> bean> 다음 단계는 방법 1과 동일합니다. 완전성을 위해 해당 단계도 게시됩니다. 3단계: 작업 예약의 트리거 방법(트리거) 구성
    8. Quartz에는 두 가지 작업 트리거, 즉
    9. org.springframework.scheduling.quartz.SimpleTriggerBeanorg.springframework.scheduling이 있습니다. 첫 번째 SimpleTriggerBean은 30분마다 한 번씩 실행되는 것과 같이 특정 빈도의 작업 호출만 지원합니다. 구성 방법은 다음과 같습니다.

    10. Xml 코드

bean

id=

"simpleTrigger"

class=

"org.springframework.scheduling.quartz.SimpleTriggerB 이안"

>

Spring 예약 작업에 대한 사용 지침property
name=
    "jobDetail"
  1. ref=

    "job2" property name =

    "startDelay"
  2. value=
  3. "0"

    /> property name="repeatInterval" value="2000" />

  4. bean> 두 번째 CronTriggerBean은 매일 12시와 같이 지정된 시간에 한 번 실행을 지원합니다. 구성 방법은 다음과 같습니다.

  5. Xml 코드

    1. bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> 속성 name="jobDetail" ref=

      "job2"
    2. />
    3. > < ;property name=

      "cronExpression"
    4. value=
    5. "0 0 12 * * ?"

      />

    6. > 위 두 가지 일정 방법은 실제 상황에 따라 선택하실 수 있습니다.

    7. 4단계: 스케줄링 팩토리 구성
    8. Xml 코드

bean class=

"org.springframework.scheduling.quartz.SchedulerFactoryBean" >

Spring 예약 작업에 대한 사용 지침
  1. 속성 name="triggers"> ref
  2. bean=
  3. "cronTrigger"

    />

    list
  4. >
  5. prop 어티

    >
  6. bean>

  7. 설명: 이 매개변수는 이전에 구성된 트리거의 이름을 지정합니다. 5단계: 애플리케이션을 시작하고 프로젝트를 tomcat이나 다른 컨테이너에 배포하세요.

  8. 이제 Spring의 Quartz 기본 구성이 소개되었습니다. 물론 사용하기 전에 해당 Spring 패키지와 Quartz 패키지를 가져와야 합니다.

    사실 Quartz의 구성이 상당히 복잡해 보인다는 것을 알 수 있습니다. Quartz는 사실 무거운 도구이기 때문에 단순히 몇 가지 간단한 예약된 작업만 실행하려는 경우 더 간단한 도구가 있습니까? ! 아래 Spring 작업에 대한 소개를 참조하세요.

    Spring-Task
  9. 이전 섹션에서는 Spring에서 Quartz를 사용하는 방법을 소개했습니다. 이번 글에서는 Spring 3.0 이후 자체 개발한 예약 작업 도구인 Spring Task를 소개합니다. 이는 경량 Quartz에 비유할 수 있으며 사용하기 쉽습니다. 매우 간단합니다. spring 관련 패키지 외에는 추가 패키지가 필요하지 않으며 두 가지 형태의 Annotation과 구성 파일을 지원합니다. 이 두 가지 방법을 아래에서 소개합니다.

    첫 번째 방법: 구성 파일 방법첫 번째 단계: 다음과 같이 작업 클래스

    즉, 일반 포조를 작성합니다.

Java 코드

  1. import org.springframework.stereotype.Service;

  2. @Service

  3. public void job1() {

  4. System.out.println("작업 입력 Progress...");
  5. }

    }
  6. 2단계: 스프링 구성 파일 헤더에 이름 지정 공간 및 설명

xmlns :작업=

"http://www.springframework.org/schema/task"

. . . . . . Spring 예약 작업에 대한 사용 지침
  1. xsi:schemaLocation=

    "http://www.springframework.org/schema/task ">

  2. 3단계: 스프링 구성 파일에서 특정 작업 설정
  3. 작업:예약됨

    ref=
  4. "taskJob"
  5. method=

    " job1"

    cron=
  6. "0 * * * * ?"
  7. />

    task:scheduled-tasks

    >

Spring 예약 작업에 대한 사용 지침
context:comComponent-scan
    base-package=
  1. " com.gy.mytask "

    />

  2. 설명: ref 매개변수 지정된 작업 클래스, 지정된 메소드는 실행해야 하는 메소드, cron 및 cronExpression 표현식입니다. 자세한 내용은 여기에 소개되지 않습니다. 이전 기사의 부록. 말할 필요도 없이 이 구성은 스프링 스캐닝 주석에 사용됩니다. 여기까지 구성이 완료되었는데, 아주 간단하지 않나요? 두 번째: 주석 형식을 사용하세요작업 클래스를 작성할 때마다 xml 파일에서 이를 구성하고 싶지 않을 수도 있습니다. @Scheduled 주석을 사용해 보겠습니다. 소스 파일: Java 코드

    1. @Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE})

    2. @Retention(RetentionPolicy.RUNTIME)

    3. @문서화됨

    4. public @interface 예약됨

    5. {

    6. public abstract String cron();

    7. public

      abstract
    8. long 고정Delay() ;
    9. public

      abstract
    10. long 고정Rate();
    11. 이 주석에는 각각 표시되는 세 가지 메서드 또는 매개변수가 있음을 알 수 있습니다. 의미: cron: cron 표현식 지정 fixedDelay: 공식 문서 설명: 이전 작업 완료 시간부터 간격이 측정되는 간격 기반 트리거입니다. 시간 단위 값은 이전 작업 완료 시간과 작업 완료 시간 사이의 간격을 의미합니다. 다음 작업 시작(밀리초) fixedRate: 공식 문서 설명: 이전 작업의 시작 시간부터 간격을 측정하는 간격 기반 트리거입니다. 시간 단위 값은 이전 작업 시작부터 다음까지의 간격입니다. 다음 작업 시작, 단위는 밀리초입니다.

    12. 다음은 구성하겠습니다.

    1단계: pojo

Java 코드 작성

import org.springframework.scheduling.annotation.Scheduled;

im port org .springframework.stereotype.Component
Spring 예약 작업에 대한 사용 지침
  1. @Component("taskJob")

  2. public

    class TaskJob {
  3. 예약됨(cron =

    "0 0 3 * * ?")

  4. public void job1() {

  5. System.out.println("작업 진행 중...") }

  6. }

  7. 스텝 2: 작업 관련 구성 추가:
  8. Xml 코드

    1. xml version="1.0" encoding="UTF-8"?>  

    2. beans xmlns="http://www.springframework.org/schema/beans"  

    3.     xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"  

    4.     xmlns:context= "http://www.springframework.org/schema/context"  

    5.     xmlns:tx="http://www.springframework.org/schema/tx"  

    6.      xmlns:task="http://www.springframework.org/schema/task"  

    7.     xsi:schemaLocation="  

    8.          "  

    9.     default-lazy-init="false">  

    10.     context:annotation-config />  

    11.     >  

    12.     context:comComponent-scan base-package="com.gy.mytask" />  

    13. >  

    14.     task:주석 기반 scheduler="qbScheduler" mode="proxy"/>  

    15.     task:scheduler id="qbScheduler" pool-size="10"/>  

참고: 이론적으로는 구성 문장만 추가하면 됩니다. 이러한 매개변수는 필요하지 않습니다.

물론 구성은 완료되었습니다. 물론 spring 작업에는 아직 많은 매개변수가 있으므로 자세한 내용은 xsd 문서를 참조하세요.

부록:

cronExpression 구성 지침, 특정 사용법 및 매개변수를 확인하세요. Baidu google

필드 허용되는 값 허용되는 특수 문자

초 0-59 , - * /

0 -5 9 , - * /

시간 0-23 , - * /

날짜 1-31 , - * ? / L W C

월 1-12 또는 JAN-DEC , - * /

평일 1-7 또는 SUN-SAT , - * ? / LC #

연도(선택 사항) 비워 두기, 1970-2099 , - * /

- 범위

* 와일드카드

? 해당 필드를 설정하고 싶지 않을 것입니다

다음은 몇 가지 예입니다.

CRON 표현식 의미

"0 0 12 * * ?" 매일 정오 12시에 트리거됨

"0 15 10 ? * *" 매일 아침 10:15에 트리거됨

"0 15 10 * * ?" 매일 아침 10:15에 트리거됨

"0 15 10 * * ? *" 매일 아침 10 : 15개 트리거

"0 15 10 * * ? 2005" 2005년 매일 아침 10시 15분에 트리거됨

"0 * 14 * * ?" 트리거

"0 0/5 14 * * ?" 매일 오후 2시부터 오후 2시 55분까지 5분마다 트리거

"0 0/5 14,18 *** ?" 오후 2시~2시 55분과 오후 6시~6시 55분의 두 시간대에

"0 0-5 14 * * ?" 매일 14:00부터 14:05까지 매분 트리거 1개

"0 10,44 14 ? 3 WED" 3월 매주 수요일 14:10 및 14:44 트리거

"0 15 10 ? * MON-FRI" 매주 월요일, 화요일, 수요일 10:15에 트리거 , 목요일과 금요일

위 내용은 Spring 예약 작업에 대한 사용 지침의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
JVM은 다른 플랫폼에서 쓰레기 수집을 어떻게 관리합니까?JVM은 다른 플랫폼에서 쓰레기 수집을 어떻게 관리합니까?Apr 28, 2025 am 12:23 AM

jvmmanagesgarbageCollectionAcrossplatformSefficialthegendercationalStrationallySticallySticallySuciationalStrationalSproachandAptingToosandHardwaredifferences.ITEMPLOYSVARIOUSCOLLECTORSLIKESERIAL, PARALING, CMS, 및 G1, 각각의 소지 firedFferentscenarios.performanceCanbetwithflags-xex : xa

Java 코드가 수정없이 다른 운영 체제에서 실행할 수있는 이유는 무엇입니까?Java 코드가 수정없이 다른 운영 체제에서 실행할 수있는 이유는 무엇입니까?Apr 28, 2025 am 12:14 AM

Java의 "Write Onge, Run Everywhere"철학은 JVM (Java Virtual Machine)에서 구현되므로 Java Code는 수정없이 다른 운영 체제에서 실행할 수 있습니다. 컴파일 된 Java Bytecode와 운영 체제 사이의 중개자로서 JVM은 바이트 코드를 특정 시스템 지침으로 변환하여 프로그램이 JVM이 설치된 모든 플랫폼에서 독립적으로 실행될 수 있도록합니다.

플랫폼 독립성을 강조하는 Java 프로그램을 컴파일하고 실행하는 프로세스를 설명하십시오.플랫폼 독립성을 강조하는 Java 프로그램을 컴파일하고 실행하는 프로세스를 설명하십시오.Apr 28, 2025 am 12:08 AM

Java 프로그램의 편집 및 실행은 Bytecode 및 JVM을 통해 플랫폼 독립성을 달성합니다. 1) Java 소스 코드를 작성하여 바이트 코드로 컴파일하십시오. 2) JVM을 사용하여 모든 플랫폼에서 바이트 코드를 실행하여 코드가 플랫폼에서 실행되도록합니다.

기본 하드웨어 아키텍처가 Java의 성능에 어떤 영향을 미칩니 까?기본 하드웨어 아키텍처가 Java의 성능에 어떤 영향을 미칩니 까?Apr 28, 2025 am 12:05 AM

Java 성능은 하드웨어 아키텍처와 밀접한 관련이 있으며이 관계를 이해하면 프로그래밍 기능이 크게 향상 될 수 있습니다. 1) JVM은 JIT 컴파일을 통해 Java Bytecode를 기계 지침으로 변환하여 CPU 아키텍처의 영향을받습니다. 2) 메모리 관리 및 쓰레기 수집은 RAM 및 메모리 버스 속도의 영향을받습니다. 3) 캐시 및 분기 예측은 Java 코드 실행을 최적화합니다. 4) 멀티 코어 시스템의 멀티 스레딩 및 병렬 처리는 성능을 향상시킵니다.

기본 라이브러리가 Java의 플랫폼 독립성을 깨뜨릴 수있는 이유를 설명하십시오.기본 라이브러리가 Java의 플랫폼 독립성을 깨뜨릴 수있는 이유를 설명하십시오.Apr 28, 2025 am 12:02 AM

기본 라이브러리를 사용하면 각 운영 체제마다 별도로 컴파일해야하기 때문에 Java의 플랫폼 독립성이 파괴됩니다. 1) 기본 라이브러리는 JNI를 통해 Java와 상호 작용하여 Java가 직접 구현할 수없는 기능을 제공합니다. 2) 기본 라이브러리를 사용하면 프로젝트 복잡성이 증가하고 다른 플랫폼에 대한 라이브러리 파일을 관리해야합니다. 3) 기본 라이브러리는 성능을 향상시킬 수 있지만,주의해서 사용해야하고 크로스 플랫폼 테스트를 수행해야합니다.

JVM은 운영 체제 API의 차이를 어떻게 처리합니까?JVM은 운영 체제 API의 차이를 어떻게 처리합니까?Apr 27, 2025 am 12:18 AM

JVM은 JNI (JavanativeInterface) 및 Java 표준 라이브러리를 통한 운영 체제 API 차이를 처리합니다. 1. JNI는 Java 코드가 로컬 코드를 호출하고 운영 체제 API와 직접 상호 작용할 수 있습니다. 2. Java Standard Library는 통합 API를 제공하며,이 API는 내부적으로 다른 운영 체제 API에 매핑되어 코드가 플랫폼에서 실행되도록합니다.

Java 9에 도입 된 모듈성은 플랫폼 독립성에 어떤 영향을 미칩니 까?Java 9에 도입 된 모듈성은 플랫폼 독립성에 어떤 영향을 미칩니 까?Apr 27, 2025 am 12:15 AM

modularityDoesNotDirectHeftJava'splatformincendence.java'splatformincendenceIngeasted whejvm, butModularItyInfluencesApplicationStructureAndmanagement, deploymentandDuffictionBecomeMoreferficaliticiboliticalWI

바이트 코드 란 무엇이며 Java의 플랫폼 독립성과 어떤 관련이 있습니까?바이트 코드 란 무엇이며 Java의 플랫폼 독립성과 어떤 관련이 있습니까?Apr 27, 2025 am 12:06 AM

bytecodeinjavaistheintermediaterepresentation attenablesplatformincendence.1) javacodeiscompiledintobytecodestoredin.2) thejvminterpretsorcompilesthisbytecodeintomachinecodeartruntime, theCodeTorUnanynanynovice를 허용합니다

See all articles

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

안전한 시험 브라우저

안전한 시험 브라우저

안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

mPDF

mPDF

mPDF는 UTF-8로 인코딩된 HTML에서 PDF 파일을 생성할 수 있는 PHP 라이브러리입니다. 원저자인 Ian Back은 자신의 웹 사이트에서 "즉시" PDF 파일을 출력하고 다양한 언어를 처리하기 위해 mPDF를 작성했습니다. HTML2FPDF와 같은 원본 스크립트보다 유니코드 글꼴을 사용할 때 속도가 느리고 더 큰 파일을 생성하지만 CSS 스타일 등을 지원하고 많은 개선 사항이 있습니다. RTL(아랍어, 히브리어), CJK(중국어, 일본어, 한국어)를 포함한 거의 모든 언어를 지원합니다. 중첩된 블록 수준 요소(예: P, DIV)를 지원합니다.

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

Atom Editor Mac 버전 다운로드

Atom Editor Mac 버전 다운로드

가장 인기 있는 오픈 소스 편집기