애초 발단은..xml책을 보다가.. 


3tier를 구분하기 위한 디자인으로.. dbhandler, htmlwrapper 클래스를 만들어 서블릿의
역할을 래핑해서 분리하는 작업중.. 서블릿,디비핸들러,htmp래퍼간 어떤 방식으로 통신
하느냐에 대해 Env 클래스(HashTable파생해서 만든클래스)를 사용하겠다는 목적으로..(유연성)

디비핸들러와 html랩퍼를 만들어 두면.. sql쿼리와 html페이지만 만들어두면 쉽게 3tier app를
만들수 있다는 설명과 함께 구현을 보여주는데..(xml or 기타 파일을 이용한 스크립트 처리)


단락중에.. 환경설정을 저장하고 로딩할때 Env vs Properties 부분에서..

1.property가 문자열/문자열 이기에.. 문자열/문자배열까지 지원을 못한다는 문제점..
2.db핸들러 환경설정은 여러줄을 실행하는 sql쿼리들인 경우가 많고.. 프로퍼티의 load메소
드는 이들을 다 수용할 유연성이 없다고 하며.. (이게 오래전책이라 그런가? 1.5에서 도입된 loadFromXML 있는데..)
3.최종적으로 임의의 레벨을 갖는 환경 변수를 설정해야 하기 때문(Env가 subEnv를 가지고 subEnv가 다시 subEnv를 갖고..
트리형식)

이 말중.. 각 Env는 내부적으로 데이터를 교류하는 여러 JavaBeans들중 하나를 나타낸다. 사실 빈즈들은
끼워넣은 Env들의 구조로 변환된 XML 도큐먼트라고 할수 있고 , XML과 마찬가지로 요소들을 임의의 레벨에
넣을수 있다. 이것은 Env클래스도 마찬가지이다.

딱 요 단락을 보고.. 스윙의 컴포넌트들은 모두가 beans규약 이다는 글귀 + 내가 작업할때 컴포넌트들에 다들..
hashset형태의 테이블이 존재했었다는것.. propertyChangeSuporter를 써본 경험등.. 

그런 기억땜에 스윙 컴포넌트들의 베이스 클래스인.. jcomponent를  분석할 필요성이 느껴졌고.. 조금 살펴보다 .. 
이런저런 위임 객체들및 .. addNotify()를 보게 되었는데.. 예전에 제대로 이해 못하고 넘어간 Object클래스의
notify메서드및 옵저버 패턴이 떠올라.. 조금 살펴보던중.. 정신이 안드로메다로 떠나버렸음.. 

(아참.. Object클래스에서 notify와 wait가 있는데.. 
서로 다른 스레드간 공유되는 락객체를 만들고.. 이 락객체를 얻고, 놓아주고 하는 방법을 통해 스레드간 통신(동기화)을
하게하는 개념이다.
Object lock객체 = new Object();  syncronized(lock){lock.wait()를 해버리면.. 현재의 스레드가 대기+락객체lock를
놓아주어 다른 스레드가 락객체를 취득할수 있게 한다.}

다른 스레드에 의해 특정 이벤트 발생시.. syncronized(lock){lock.notify()식으로 하면.. 저 위에 멈췄던 스레드 다시
가동(throw InterruputException을 통해서 = 예외 핸들링 방식.. 물론 중간에 새로운 스레드를 생성및 동작시키는 등의 
처리도 가능하고.. 내 맘대로지..} => 결국 스레드간 이벤트 방식으로 동작시킬수 있음.

예전 단순 멀티스레드 서버 구현시 어셉,리드 작업의 비동기 처리를 위해 어셉 스레드에서 어셉후, 리드 스레드를
생성해서 동작시키는 방식이었지만.. wait,notify를 이용한다면.. 서버 처음 시작부터.. 어셉스레드 동작, 리드 스레드
동작시키고.. 지들끼리 내부적으로 wait/notify로서 생산자/소비자 방식으로 순차적 처리가 가능함. 

물론 위의과정은 스레드가 각각 하나씩인 단순한 경우로서.. 더 복잡해질 경우.. 어셉 스레드풀 + 어셉용 스레드 3개
리드용 스레드풀 + 리드용 스레드 10개라면.. 어셉 스레드들과 리드 스레드들간의 생산/소비자 방식의 순차적 처리+
어셉스레드는 자기들끼리, 리드스레드는 자기들끼리 동기화를 시켜줘야함.(지들끼린 코드를 공유하니.. 메서드의
선언에 synchronized를 한다던가 하는 식 또는 공유 데이터를 동기화 객체(콘커런시인가 하는 패키지)으로.. 동기화 처리)

실제 구현은 안해봄;;  결국.. 작업 시작해라=notify, 작업 잠시 멈춰라=wait 라는 .. 이벤트 객체인 셈임..
이벤트 처리 방식은 .. 전에 잠깐 살펴본 생산자/소비자 패턴임. = 예전 nio할때.. 어셉용 스레드가 큐=fifo에 클라이언트 
메세지들을 넣어두고.. 큐객체가 발송 작업용 스레드1놈만 호출해서 작업시키는 방식이랄까? 물론.. 큐의 원소 하나당
스레드 하나씩이지.. 전체를 스레드 하나가 처리하는건 아님;;)
*****************************************************************8

여튼 xml등 파일을 통한.. 설정의 저장/로드를 통한 초기화는 다른 프레임워크.. 스프링/스트럿츠등에서도 사용하는 개념
이기에 뚤어둘 필요가 있음;; ..초 간단하게 개념잡자면.. xml파일에 readObject/writeObject 함으로서 확장성 높이고,
결합성 줄이고..문자열이라 사람이 이해하기 쉽고..
(현재 xml책을 보다->grep코드를 보다->스윙책중 document부분을 보다.. -> 인터넷에서 jcomponent를 찾고있는중;;;)


결론: 자바 api클래스들중 특히 gui클래스들.. 정말 더럽게 복잡하고.. 거대하고.. 사람 환장하게 함;;

jcompent가 임포트하는 클래스만 해도.. OTL


 import java.util.HashSet;
29  import java.util.Hashtable;
30  import java.util.Dictionary;
31  import java.util.Enumeration;
32  import java.util.Locale;
33  import java.util.Vector;
34  import java.util.EventListener;
35  import java.util.Set;
36  import java.util.Map;
37  import java.util.HashMap;
38  
39  import java.awt.*;
40  import java.awt.event.*;
41  import java.awt.image.VolatileImage;
42  import java.awt.Graphics2D;
43  import java.awt.peer.LightweightPeer;
44  import java.awt.dnd.DropTarget;
45  import java.awt.font.FontRenderContext;
46  import java.beans.PropertyChangeListener;
47  import java.beans.VetoableChangeListener;
48  import java.beans.VetoableChangeSupport;
49  import java.beans.Transient;
50  
51  import java.applet.Applet;
52  
53  import java.io.Serializable;
54  import java.io.ObjectOutputStream;
55  import java.io.ObjectInputStream;
56  import java.io.IOException;
57  import java.io.ObjectInputValidation;
58  import java.io.InvalidObjectException;
59  
60  import javax.swing.border.*;
61  import javax.swing.event.*;
62  import javax.swing.plaf.*;
63  import static javax.swing.ClientPropertyKey.*;
64  import javax.accessibility.*;
65  
66  import sun.swing.SwingUtilities2;
67  import sun.swing.UIClientPropertyKey;


by givingsheart 2014. 1. 2. 09:41
멀티스레드 환경에서 이뮤터블 패턴이 장점을 가짐. 즉 스레드간 특정 자원을 공유하는
문제에 대해 방지가 가능. 물론 concurrent패키지 계열의 클래스들을 사용해도 될테지만..
그래서 string이 이뮤터블이 된듯(물론 풀링도 가능하고).. 흐음.. 원본을 두고 사본을 건낸다..
어제 ejb패턴에서도 봤듯.. 서버측에서 데이터에 대해 클라가 요청시 사본을 생성해서 보내주
는 의미를 고민해볼것


lock관련

http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html



동기화 관련

생산자,소비자 패턴


생뚱맞지만.. 예전에 bean xmlencoder xmldecoder .. 스윙 컴포넌트(bean베이스)의 정보를 xml로..


글고 property change 서포터..


오픈소스 관련


************************************************************************************

생뚱2.. 스윙 유틸의 메서드중.. addnotify..  awt.frame -> awt.window -> awt.container -> awt.component까지.. 환장함..

Makes this Component displayable by connecting it to a native screen resource. This method is called internally by 

the toolkit and should not be called directly by programs.
This method changes layout-related information, and therefore, invalidates the component hierarchy.

Since:
JDK1.0

See also:
isDisplayable()
removeNotify()
invalidate()


6855 
6856     public void More ...addNotify() {
6857         synchronized (getTreeLock()) {
6858             ComponentPeer peer = this.peer;
6859             if (peer == null || peer instanceof LightweightPeer){
6860                 if (peer == null) {
6861                     // Update both the Component's peer variable and the local
6862                     // variable we use for thread safety.
6863                     this.peer = peer = getToolkit().createComponent(this);
6864                 }
6865 
6866                 // This is a lightweight component which means it won't be
6867                 // able to get window-related events by itself.  If any
6868                 // have been enabled, then the nearest native container must
6869                 // be enabled.
6870                 if (parent != null) {
6871                     long mask = 0;
6872                     if ((mouseListener != null) || ((eventMask & AWTEvent.MOUSE_EVENT_MASK) != 0)) {
6873                         mask |= AWTEvent.MOUSE_EVENT_MASK;
6874                     }
6875                     if ((mouseMotionListener != null) ||
6876                         ((eventMask & AWTEvent.MOUSE_MOTION_EVENT_MASK) != 0)) {
6877                         mask |= AWTEvent.MOUSE_MOTION_EVENT_MASK;
6878                     }
6879                     if ((mouseWheelListener != null ) ||
6880                         ((eventMask & AWTEvent.MOUSE_WHEEL_EVENT_MASK) != 0)) {
6881                         mask |= AWTEvent.MOUSE_WHEEL_EVENT_MASK;
6882                     }
6883                     if (focusListener != null || (eventMask & AWTEvent.FOCUS_EVENT_MASK) != 0) {
6884                         mask |= AWTEvent.FOCUS_EVENT_MASK;
6885                     }
6886                     if (keyListener != null || (eventMask & AWTEvent.KEY_EVENT_MASK) != 0) {
6887                         mask |= AWTEvent.KEY_EVENT_MASK;
6888                     }
6889                     if (mask != 0) {
6890                         parent.proxyEnableEvents(mask);
6891                     }
6892                 }
6893             } else {
6894                 // It's native. If the parent is lightweight it will need some
6895                 // help.
6896                 Container parent = getContainer();
6897                 if (parent != null && parent.isLightweight()) {
6898                     relocateComponent();
6899                     if (!parent.isRecursivelyVisibleUpToHeavyweightContainer())
6900                     {
6901                         peer.setVisible(false);
6902                     }
6903                 }
6904             }
6905             invalidate();
6906 
6907             int npopups = (popups != null? popups.size() : 0);
6908             for (int i = 0 ; i < npopups ; i++) {
6909                 PopupMenu popup = (PopupMenu)popups.elementAt(i);
6910                 popup.addNotify();
6911             }
6912 
6913             if (dropTarget != null) dropTarget.addNotify(peer);
6914 
6915             peerFont = getFont();
6916 
6917             if (getContainer() != null && !isAddNotifyComplete) {
6918                 getContainer().increaseComponentCount(this);
6919             }
6920 
6921 
6922             // Update stacking order
6923             updateZOrder();
6924 
6925             if (!isAddNotifyComplete) {
6926                 mixOnShowing();
6927             }
6928 
6929             isAddNotifyComplete = true;
6930 
6931             if (hierarchyListener != null ||
6932                 (eventMask & AWTEvent.HIERARCHY_EVENT_MASK) != 0 ||
6933                 Toolkit.enabledOnToolkit(AWTEvent.HIERARCHY_EVENT_MASK)) {
6934                 HierarchyEvent e =
6935                     new HierarchyEvent(this, HierarchyEvent.HIERARCHY_CHANGED,
6936                                        this, parent,
6937                                        HierarchyEvent.DISPLAYABILITY_CHANGED |
6938                                        ((isRecursivelyVisible())
6939                                         ? HierarchyEvent.SHOWING_CHANGED
6940                                         : 0));
6941                 dispatchEvent(e);
6942             }
6943         }
6944     }



by givingsheart 2014. 1. 2. 09:40
심심해서 예전에 전혀 감을 못잡았던.. 머지소트 조인을 찾아보다 찾은 블로그;; (db.. 묵혀둬서 미안하다;;)

http://blog.naver.com/thesot?Redirect=Log&logNo=70130988563



웹 해킹관련.. (이것은 나~중에..)



(추가)

DB를 포기해야 한다. 혼자서 모든걸 할수가 없다. 이러다간 죽도 밥도 안된다.

by givingsheart 2014. 1. 2. 09:39