[자바] 동적 클래스 생성 및 멀티 쓰레드 사용한 배치 프로그램.

2016. 3. 7. 16:53IT/Web-Java

안녕하세요.

동적 클래스 생성 및 멀티 쓰레드를 사용한 배치 프로그램을 만들어 봤습니다.

보안상 소스를 통으로 못 가지고 나오고 프로젝트가 종료되면서 특정 부분만 프린팅해서 나올 수 있어서,

변수 및 메소드가 현재 포스팅에서 구현되지 않은 건 타이핑을 하다보니 전부 다 타이핑하기에는 힘들어서요;;;

그래서 중요한 부분만 주석 및 코딩을 해보았습니다..


1. 쓰레드를 생성하여 실행할 메인 컨트롤러 안의 중요 내용

   동적 클래스를 생성하여 쓰레드로 실행.. 돌아보니.. 쓰레드 관련 여러 문제가 발생할 소지가 다분히.. '';;; ㄷㄷㄷ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    try {
    //******** S:동적 클래스 로딩을 위한 생성자 타입 설정 ********//
    Class paramForm[] = new Class[7];
    paramForm[0= String.class;            // maxResultSeq
    paramForm[1= String.class;            // maxDetailSeq
    paramForm[2= String.class;            // batchTargetId
    paramForm[3= String.class;            // batchFromDate
    paramForm[4= String.class;            // batchToDate
    paramForm[5= String.class;            // args[0]
    paramForm[6= String.class;            // 배치 수행 index Seq
    //******** E:동적 클래스 로딩을 위한 생성자 타입 설정 ********//
 
    //******** S:동적 클래스 생성 ********//
    ArrayList<HashMap<String, Object>> targetList = selectRecentTargetList();        // HashMap타입의 ArrayList
    HashMap<String, Object> map = null;
 
    for(int i = 0 ; i < targetList.size() ; i++) {
        map = (HashMap<String, Object>)targetList.get(i);
 
        maxDetailSeq = (String)map.get("MAX_DETAIL_SEQ");                    // 배치 상세 SEQ
        batchFromDate = (String)map.get("BATCH_FROM_DATE");                    // 배치 대상기간 : From
        batchToDate = (String)map.get("BATCH_TO_DATE");                        // 배치 대상기간 : To
        targetId = (String)map.get("BATCH_TARGET_ID");                        // 배치 대상 타겟 ID >> 예) 0101A01
 
        packCd = targetId.substring(02);         // 패키지를 구분할 Id값 자르기 >> 예) 06
        // 동적 클래스 생성을 위한 풀 클래스명 만들기 >> 예) batchNew.C01.SampleBatch_0101A01
        String targetBatch = "batchNew.C"+packCd+".SampleBatch_"+targetId;    
        // 동적 클래스 로딩
        Class batchClass = Class.forName(targetBatch);
        // 로딩된 동적 클래스 생성자 선언
        Constructor const = batchClass.getConstructor(paramForm);
        // 폼만 있는 생성자 파라미터에 값 세팅
        Object argsList [] = new Object[7];
        argsList[0= new String(maxResultSeq);                // MAX 배치 결과 SEQ +1        
        argsList[1= new String(maxDetailSeq);                // MAX 배치 히스토리 SEQ +1
        argsList[2= new String(targetId);                    // 배치 대상 ID
        argsList[3= new String(batchFromDate);            // 배치 대상기간 : From
        argsList[4= new String(batchToDate);                // 배치 대상기간 : To
        argsList[5= new String(args);                        // 입력받은 커넥션 인자값
        argsList[6= new String(String.valueOf(i+1);        // 몇번째 배치인지 구분할 배치 인덱스 SEQ
 
        Object realBatchClass = ct.newInstance(argsList);    // 실질적 동적 클래스 인스턴스 생성 완료
        //******** E:동적 클래스 생성 ********//
        
        //******** S:생성된 동적 클래스를 기반으로 배치 쓰레드 실행 ********//
        Runnable r = (Runnable)realBatchClass;
        // r.run(); // 이렇게 하면 순차적으로 실행되던데.. 제가 개념을 아직 잘 이해를 못한 것 같네요ㅠ 쓰레드 어렵당
 
        Thread t = new Thread(r);    // 쓰레드 객체 생성
        t.start();    // 쓰레드 실행
 
        // 쓰레드 객체 우선순위 지정 >> 선행배치의 경우 우선적으로 선점하여 수행한다.
        if("9901C01".equals(targetId) || "8801C02".equals(targetId) || "7701C03".equals(targetId)) {
            t.join();
        }
    }
    //******** E:동적 클래스 생성 ********//
catch(Exception e) {    // 이클립스 자동으로 생성했더니 익셉션은 되게 다양하게.. 걸리던데.. classnotfound부터 해서.. 엄청 많음.. 
    e.printStackTrace();
}
cs



2. 실제 배치 수행 클래스(여기도 생략...생략...생략...ㅎㅎ)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class Batch_0101C01 extends Thread {
    // ************ S:생성자에서 사용할 파라미터 ************ //
    private String batchResultSeq = "";        // 배치 결과 Seq
    ...
    // ************ E:생성자에서 사용할 파라미터 ************ //
    // 생성자
    public Batch_0101C01(String batchResultSeq ... ) {
        this.batchResultSeq = batchResultSeq;
        ...
    }
    /**
      * 배치 프로세스 
      */
    public void run() {
        Connection conn = null;                        // 커넥션
        QueryUtility qu = null;                        // 커넥션을 맺을 유틸리티
        BatchUtility bu = new BatchUtility(arg);    // 배치 관련 공통으로 사용했던 유틸리티
        String[] strErr = null;                     // 처리결과
        
        try {
            qu = new QueryUtility();                // QueryUtility 객체 생성
            conn = qu.getConnectionBatch(args);        // 커넥션 형성
            conn.setAutoCommit(false);                // 트랜잭션 처리를 위한 autoCommit 방지
            
            // **************** S:배치 프로세스 수행 **************** //
            System.out.println(" 배치 관련해서 output에 보여줄 로그를 만들어요.");
            // 배치 수행 프로세스에 여러가지 방법들이 있겠지만 저 같은 경우는 
            // 1.배치 기본정보를 우선적으로 입력
            // 2.배치 시작시작 입력
            // 3.기존 배치 데이터 초기화(프로그램 특성상 데이터 초기화 먼저 함)
            // 4.데이터 적재 배치 수행
            // 5.기타 배치 정보 입력
            // 6.배치 수행 종료 시간 입력
            // 7.commit
            
            // 각 단계별 예외 처리 메소드를 감싸주었고, 선행 단계가 이상이 없을 경우 다음 단계의 로직을 수행하였습니다.    
            // 각 단계별 수행은 별도의 메소드를 구현하였습니다. 저어어얼대 run() 메소드 안에 코딩 안함 ㅋㅋ
        } catch(Exception e) {
            e.printStackTrace();
        } ... // 익셉션 생략
    }
}
 
cs


뭐... 정말 생략을 많이 했어요... 그래도 필요한게 있으신분들은 알아서 뽑아서 보시겠죠...?

저도 나중에 다시 보면 내가 왜 이렇게 코딩했지?라고 할지도...ㅠㅠㅋ