달력

5

« 2024/5 »

  • 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

'I.tistory()'에 해당되는 글 290

  1. 2010.04.02 Spring 트랜잭션 격리 수준, 전달 행위의 값
  2. 2010.04.01 SOAP( Simple Object Access Protocol) 이란?
  3. 2010.03.30 26일 (Final)
  4. 2010.03.29 25일차
  5. 2010.03.29 자바 리플랙션 (Java Reflection) 1
  6. 2010.03.26 24일차 1
  7. 2010.03.26 AOP 용어
  8. 2010.03.25 23일차 1
  9. 2010.03.24 22일차
  10. 2010.03.24 자바의 abstract와 인터페이스(Interface)
.. .. ..


* 트랜잭션 격리 수준

 격리수준 설명 
 ISOLATION_DEFAULT PlatformTransactionManager의 기본 격리수준으로 대부분의 데이터베이스에 ISOLATION_READ_COMMITTED가 적용된다. 
 ISOLATION_READ_UNCOMMITTED 가장 낮은 수준의 격리수준이다. 즉, 이 트랜잭션이 수정한 데이터는 심지어 커밋하기도 전에 다른 트랜잭션이 볼 수 있기 때문에 실제로 이것을 격리수준이라고 부를 수는 없다. 또한 이 트랜잭션은 다른 트랜잭션이 커밋을 하기 전에 변경내용ㅇ을 볼수있다. 
 ISOLATION_READ_COMMITED 대부분의 데이터베이스에서 지원하는 기본 격리수준으로 트랜잭션이 완료하기 전에는 데이터에 대한 수정사항을 다른 트랜잭션들이 볼 수 없도록 명시한다. 하지만 다른 트랜잭션이 커밋한 입력/ 수정 데이터를 조회 할수이 ㅆ다. 이것은 다른 트랜잭션이 수정한 데이터를 볼 수 있기 때문에 트랜잭션의 시점에 따라 다른 데이터를 볼 수 있다는 것을 의미한다. 
 ISOLATION_REPEATABLE_READ ISOLATION_READ_COMMITTED보다 엄격한 격리수준으로 트랜잭션 내에서 데이터를 조회하는 경우 다른 트랜잭션이 조회 대상 데이터를 변경하였다고 하더라도 적어도 처음과 동일한 데이터를 조회할 수 있도록 ㅈ보장해준다. 그러나 다른 트랜잭션이 새로운 데이터를 입력하였다면 새롭게 입력된 데이터를 조회할 수 있게 된다. 
 ISOLATION_SERIALZBLE 가장 비용이 많이 들고 신뢰도가 높은 격리수준이다. 모든 트랜잭션은 한번에 하나씩 순차적으로 실행된다. 


* 전달 행위의 값

 전달행위 설명 
 PROPAGATION_REQUIRED 활성화된 트랜잭션이 존재한다면 스프링은 이 트랜잭션을 사용하고 그렇지 않다면 새로운 트랜잭션을 시작한다.  
 PROPAGATION_ SUPPORTS  활성화된 트랜잭션이 존재한다면 스프링은 이 트랜잭션을 사용하지만 활성화된 트랜잭션이 없다면 새로운 트랜잭션을 시작하지 않는다.
 PROPAGATION_MANDATORY  활성화된 트랜잭션이 존재한다면 스프링은 이 트랜잭션을 사용하지만 활성화된 트랜잭션이 없다면 스프링은 예외를 던진다.
 PROPAGATION_REQUIRES_NEW 스프링은 항상 새로운 트랜잭션을 시작한다. 만약 활성화된 트랜잭션이 이미 존재한다면 이 트랜잭션은 잠시 중지된다.
 PROPAGATION_ NOT_SUPPORTED  스프링은 활성화된 트랜잭션 내에서 코드를 실행하지 않는다. 코드는 항상 트랜잭션이 아닌 상태에서 실행되며 기존에 존재하는 트랜잭션이 있다면 모두 잠시 중지시킨다.
  PROPAGATION_NEVER 활성화된 트랜잭션이 존재해도 항상 트랜잭션 없이 코드를 실행한다. 만약 활성화된 트랜잭션이 존재한다면 예외를 던진다.
  PROPAGATION_NESTED  활성화된 트랜잭션이 존재 하면 중텁된 트랜잭션 내에서 실행된다. 만약 활성화된 트랜잭션이 없다면 코드는 TransactionDefinition.PROPAGATION_REQUIRED가 설정된 것처럼 실행된다.

'I.lib() > I.lib(Spring)' 카테고리의 다른 글

CronTrigger (잡 스케쥴링)  (1) 2010.04.08
Spring Annotation (스프링 어노테이션)  (1) 2010.04.06
AOP 용어  (0) 2010.03.26
Spring ppt 모음  (1) 2010.03.24
Spring Tutorial  (0) 2010.03.24
.
:
Posted by .07274.
.. .. ..


SOAP 란 ?


 SOAP은 웹상의 객체들을 액세스하기 위한 마이크로소프트의 프로토콜이다.

이 프로토콜은 HTTP를 사용하여 인터넷에 텍스트 명령어를 보내기 위해 XML 구문을 쓴다. 
 SOAP은 COM, DCOM, 인터넷 익스플로러, 마이크로소프트의 자바 이행 등 내에서 지원된다.


왜 SOAP 인가?


 인터넷을 통해 기업과 기업, 기업과 고객의 장벽이 없어진 상황에서 서로 다른 인프라를 바탕으로 하는 컴포넌트를 연결하는 방법이 절실한 현실에서 JAVA, CORBA, COM 등의 주요 컴포넌트 기술은 독자적인 인프라와 기술을 사용하므로 상호 운용성이 크게 떨어지게 마련이다.

 즉, 현재의 주 컴포넌트 기술로 일컬어지는 JAVA, CORBA, COM 등은 목적은 비슷하지만 목적을 구현하는 방법은 매우 다르므로 호환성을 기대하기 어렵다.

 예를 들어보자.

 상호 운용에 필요한 하나의 요소는 컴포넌트를 액세스하기 위한 타입(클래스, 인터페이스)이다.

CORBA와 COM은 IDL에 기반한다는 공통점이 있지만, IDL 문법에 차이가 많으며 IDL이 생성한 컴포넌트의 타입 정보를 제공하는 방법 역시 공통점을 찾기 어렵다. 반면 JAVA는 IDL을 사용하지 않고 언어 자체가 갖는 타입 정보를 이용한다. 또한, 상호 운용에서 중요한 것은 통신 메커니즘이지만 CORBA는 IIOP(Internet Inter-ORB Protocol)를, 자바는 RMI(Remote Method Invocation)를, COM은 DEC RPC(Remote Procedure Call)을 사용한다. 그리고 이들 통신 메커니즘 역시 공통점이 없다.

이들 컴포넌트 기술들은 고유의 장단점을 갖고 있으며, 어는 것이 다른 것에 대해 우월하다거나 뒤진다고 말할 수 없다. 또한 수년에 걸쳐 많은 자원과 시간을 투자한 고유의 추종자들을 거느리고 있으므로 JAVA, CORBA, COM 중 어느 하나가 사라질 것으로 예견하는 이는 아무도 없을 것이다. 더욱 문제되는 것은 이들 중 어느 한 기술이 인터넷을 지배하고 있거나, 지배할 가능성 역시 거의 없다는 것이다. 이것이 현재의 컴포넌트 기술들이 갖는 상호 운용성의 큰 문제가 되는 것이다.



결국 해결책은 SOAP ?


SOAP은 XML과 HTTP를 사용해 플랫폼에 독립적으로 서비스 혹은 분산 객체를 액세스하는 방법을 정의한다.


HTTP는 인터넷 표준이며 누구나 어떠한 플랫폼에서도 사용할 수 있는 프로토콜이다.

그 어떤 개인이나 기업도 HTTP를 인정한다. XML은 HTTP보다 상대적으로 늦게 나온 기술이지만 최근 들어 널리 사용되며 업계 표준으로 자리잡고 있다. 또한 HTTP와 XML은 공통적으로 텍스트에 기반하고 있으므로 이들을 처리하는 소요 비용(프로세싱 시간, 메모리 등)은 상대적으로 매우 적다. 텍스트 문자열을 제어하고 TCP/IP에 접근할 수 잇는 어떠한 응용 프로그램도 HTTP를 통해 XML데이터를 전송하거나 수신할 수 있다는 것이다. 이러한 손쉬운 사용성은 이들 두 기술이 빠르게 IT 환경에 적응하는 발판이 됐다.

 SOAP은 이런 XML과 HTTP를 사용함으로써 이들이 갖는 장점을 모두 포함하면서 컴포넌트의 상호 운용성을 높일 수 있는 것이다.


SOAP의 장점


  • 독립성

     
 SOAP은 XML과 HTTP를 이용해 어떤 인터페이스의 메쏘드를 호출할 것이며, 이 메쏘드에 대한 매개변수를 알리는 역할만 담당한다. 따라서 실제 컴포넌트를 생성하거나 컴포넌트에 대한 직접적인 호출에 관여하지 않는다.

 즉, SOAP은 컴포넌트를 활성화하는 방법이나 호출 방법에 대해 전혀 관여하지 않으며, 이에 대한 상세한 것은 HTTP Request를 수신하는 수신자에게 위임하고 있다. 따라서 객체 지향 기술이나 컴포넌트 기술을 사용하지 않는 애플리케이션일지라도 SOAP을 통해 객체 서비스를 제공하거나 제공받을 수 있다.

 결론적으로 말해, SOAP은 JAVA, CORBA, COM 등의 분산 객체 기술에 구애받지 않는 프로토콜이며 심지어 이들 분산 객체 기술을 전혀 사용하지 않는 애플리케이션도 SOAP을 통해 원격 프로시져 호출이나 데이터 전송을 수행할 수 있다. SOAP이 원격 객체의 구현에 대해 언급하고 있지 않으므로, 원격 객체는 어떤 프로그래밍 언어로도 구현할 수 있다.
 
  • 인터넷 적용성

 SOAP은 transport로서 HTTP를 사용한다.
 HTTP를 사용함으로써 얻을 수 있는 장점은 인터넷에서 널리 사용할 수 있다는 점이다.
 실제로 SOAP은 인터넷에서 원격 객체를 액세스하기 위해 고안된 프로토콜이다.
 그렇다면 기존 객체 지향 기술은 인터넷에서 문제가 있었던 것인가 살펴보도록 하자.

 JAVA, CORBA, COM 등이 사용하는 transport는 고유의 transport로서 RMI, IIOP, DCOM을 사용하지만, 이들 프로토콜은 TCP/IP 포트를 동적 할당하는 메커니즘을 사용하고 있다. 이것 때문에 이들 프로토콜이 방화벽을 통과하는데 문제점이 드러난다.

 예를 들어 DCOM을 인터넷에서 사용하려면 방화벽에 일정 영역의 TCP/IP 포트를 열어 놓아야 하는데, 이것은 방화벽을 사용하지 않는 것과 다름없게 만들어 버린다.
 반면 대부분의 기업 네트워크는 자사의 웹 사이트를 위해 HTTP가 사용하는 포트를 열어 놓고 있다.

 SOAP은 HTTP를 사용하므로 아무런 문제 없이 방화벽을 통과할 수 있다. 또한 대부분의 방화벽 제품은 HTTP 헤더의 내용을 읽어 필터링을 수행할 수 있으므로 특정 인터페이스의 특정 메쏘드를 호출하는 SOAP 메시지만을 통과시키도록 설정할 수도 있다.

 SOAP은 HTTP를 통해 인터넷에 분산된 객체들에 접근할 수 있으며 방화벽이나 HTTPS 등의 인터넷 보안 기술을 그대로 적용받을 수 있는 것이다.
 
  •  표준

 SOAP 탄생의 주역은 마이크로소프트와 IBM이다.

 초기 마이크로소프트 제품의 대부분이 자사의 고유한 기술을 사용했던 것과 반대로 최근 마이크로소프트의 제품들은 업계 표준이나 인터넷 표준을 준수하기 시작했다. SOAP 역시 인터넷 표준으로서 XML과 HTTP를 채택하고 있으며 SOAP 자체 역시 W3C에 표준으로서 제출된 상태이다. 2001년 초 현재 W3C에 제출됐고 검토되고 있는 SOAP의 최신 버전은 스펙 1.1이다.


 SOAP이 W3C로부터 공식 표준으로 인정받을 것은 확실시 되고 있으며 플랫폼과 운영체제, 애플리케이션 그리고 프로그래밍 언어를 뛰어넘는 분산 객체 프로토콜로 자리잡을 가능성 역시 매우 높다. 


출처 [http://www.saga21.net/417]
글쓴이 [사가]

.
:
Posted by .07274.
2010. 3. 30. 21:33

26일 (Final) I.edu()/I.edu(S&S)2010. 3. 30. 21:33

.. .. ..
*7~8시
- 고도화 : application 을 extension , version up , 필요사항 추가하는 것. (주기적(4~5년)으로 시행)
*8~9시
           - javaservice.net  <- Java site.
           
*9~10시
           - Finish.          
 

'I.edu() > I.edu(S&S)' 카테고리의 다른 글

25일차  (0) 2010.03.29
24일차  (1) 2010.03.26
23일차  (1) 2010.03.25
22일차  (0) 2010.03.24
21일차  (0) 2010.03.23
.
:
Posted by .07274.
2010. 3. 29. 21:46

25일차 I.edu()/I.edu(S&S)2010. 3. 29. 21:46

.. .. ..
 *7~8시
- review
- Clone 함수    1. shadow copy : 복사한후 원본이 변하여도 clone된 객체는 변하지 않는다.
                      2. deep copy     : 복사한후 원본이 변하면 clone된 객체도 함께 변화한다.
- reflect ( java.lang.reflect )       : class에 관련된 동적정보나, 구조적인 정보 및 환경정보등을 알기위해 사용.
                                                bigging java때 주로 배운다.
- Spring AOP는 론타임 Proxy 방식이기 때문에 this와 target 지시자는 같은 객체를 참조하며
   @target과 @within 지시자 역시 가튼 객체를 참조한다.
- 예외처리의 규칙작성
   + 비지니스 로직을 수항해는 중 발생하는 비지니스 오류는 Checked Exception 으로 처리하고 
     그렇지 않으면 Unchecked Exception 으로 처리
   + Checked Exception 중 사용자가 인지해야 되는 Exception 은 해당 메시지 출력 한다.
- 마샬링  : 통신에서 사용하는 기술로 데이터를 보낼때 겉에 랩을싸고 그위에 마샬링을 하여 데이터의 손실을 막는다.
*8~9시
            - 스프링의 모든 DAO 템플릿 클래스는 스레드에 안전하기 때문에 애플리케이션 내의 각각의 DataSource에
               대해서 하나의 Jdbc Template 인스턴스만을 필요로 한다.
            - StringBuilder란?!
            - PlaceHolder는 ? 도 가능하지만 :a,:b로도 대체 사용이 가능하다.
               + :a, :b는 파라미터를 찾아가는것
            - PreparedStatement와 Statement의 차이점.
              + 전자는 미리 메모리에 올린상태로 사용하는 것이고 후자는 필요할때만 불러다 사용하는 것이다.
                단순 일회성 쿼리 사용시에는 후자를 사용함이 비용 소모가 적다.
           
           - Spring JDBC - Transaction의 격리레벨
1. Read Uncommitted(커밋되지않은읽기)
  한사용자가 "A"라는데이타를"B" 라는 데이타로 변경하는 동한 다른 사용자는 "B” 라는 아직완료되지않은 
  Uncommitted  혹은 Dirty 데이터"B"를읽을수있다. 다른트랜잭션에서커밋하지않은데이타를읽을수있음
2. Read Committed (커밋된읽기)
  SELECT 문장이 수행되는 동안 해당 데이터에 Shared Lock이 걸립니다. 그러므로, 어떠한 사용자가 A라는
  데이터를 B라는 데이터로 변경하는 동안 다른 사용자는 해당 데이터에 접근할수없습니다. 다른 트랜잭션에 의해
  커밋된데이터를읽을수있다.
3. Repeatable Read (반복읽기)
  트랜잭션이 완료 될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는
  그 영역에 해당되는 데이터에 대한 수정이 불가능합니다. 가령, Select col1 from A where col1 between 1 and 10을
  수행 하였고 이 범위에 해당하는 데이터가 2건이 있는경우(col1=1과5)  다른 사용자가 col1이 1이나5 인 Row에 대한
  UPDATE이 불가능합니다. 하지만, col1 이 1 과 5 를 제외한 나머지 이 범위에 해당하는 Row를 INSERT하는것이 
  가능합니다.처음에읽어온데이타와두번째읽어온데이타가동일한값을갖는다.
4. Serializable (직렬혹은순차기능)
  트랜잭션이 완료 될 때까지 SELECT 문장이 사용하는 모든 데이터에 Shared Lock이 걸리므로 다른 사용자는 그 
  영역에 해당되는 데이터에 대한 수정 및 입력이 불가능합니다. 예를 들어, Repeatable Read의 경우 1 에서 10  사이에
  해당되는 데이터에 대한 UPADTE이 가능 하였습니다. 하지만 이 Level에서는 UPDATE 작업도 허용하지 않습니다. 
  동일한 데이터에 대해서 동시에 두개 이상의 트랜잭션이 수행 될 수없다
 
*9~10 시
           - Spring doc 교육 종료. 질의시간.
          
 
 

'I.edu() > I.edu(S&S)' 카테고리의 다른 글

26일 (Final)  (0) 2010.03.30
24일차  (1) 2010.03.26
23일차  (1) 2010.03.25
22일차  (0) 2010.03.24
21일차  (0) 2010.03.23
.
:
Posted by .07274.
2010. 3. 29. 14:19

자바 리플랙션 (Java Reflection) I.lib()/I.lib(Java)2010. 3. 29. 14:19

.. .. ..
일상에서의 리플렉션(reflection)이란 거울 속에 비친 자신의 모습입니다. 프로그래밍 세상에서의 리플렉션은 프로그램이 자신의 모습을 보고 심지어 수정하기 까지 하는 것을 말합니다. Java reflection API는 바로 그런 기능을 언어의 기본 요소인 클래스, 필드, 메소드를 들여다 볼 수 있는 평범한 Java API를 통해 제공합니다. 리플렉션을 이해하는 것은 여러분이 자주 사용하는 툴을 이해하는데 도움이 됩니다. Eclipse가 어떻게 자동완성으로 메소드 이름을 만들어 줄까? Tomcat은 web.xml파일에 있는 클래스 이름을 가지고 웹의 요청을 처리할 서블릿을 실행하는 걸까? Spring은 어떻게 마술 같은 dependency injection을 하는 것일까? 여러분의 프로그램에서도 리플렉션을 사용하여 보다 동적이고 유연한 코드를 작성하실 수 있습니다. 리플렉션을 사용하면 이전에 본적 없는 클래스들을 매우 멋지게 처리할 수 있습니다.

클래스 만들기

이미 말했듯이 리플렉션의 기본 아이디어는 프로그램이 동작하는 내부에 집어 넣을 API를 제공하는 것입니다. Java에서 가장 기본이 되는 사상이 바로 클래스기 때문에(클래스 없이 자바 프로그램을 만들어 보세요) Class 클래스부터 살펴보는 것이 좋겠습니다. 이것의 객체는 Class 타입일 것입니다. 일단 Class객체를 가지게 되면 그것으로부터 클래스에 관련된 모든 정보를 뽑아낼 수 있습니다. 클래스의 이름, 그것이 public 인지 abstract 인지 final 인지 그리고 심지어 상위 클래스까지 말이죠.

이 정도면 이론은 충분합니다. 자, 이제 리플렉션 현미경을 가지고 아래에 있는 매우 간단한 Employee 클래스를 살펴봅시다.
package com.russolsen.reflect;

public class Employee{
   public String _firstName;
   public String _lastName;
   private int _salary;

      public Employee()   {
      this( "John", "Smith", 50000);
   }
 
   public Employee(String fn, String ln, int salary)   {
      _firstName = fn;
      _lastName = ln;
      _salary = salary;
   }
   
   public int getSalary()   {
      return _salary;
   }
   
   public void setSalary(int salary)   {
      _salary = salary;
   }
   
   public String toString()    {
      return "Employee: " + _firstName +  " "
             + _lastName + " " + _salary;
   }

}
Class 객체를 만드는 가장 쉬운 방법은 해당 클래스 객체의 getClass 메소드를 호출하는 것입니다. 아래에 있는 코드는 Employee 객체를 만들고 그것의 Class 객체를 만들어서 클래스에 대한 다양한 정보들을 출력합니다.
package com.russolsen.reflect;

import java.lang.reflect.Modifier;

public class GetClassExample{
   public static void main(String[] args)   {
 
      Employee employee = new Employee();
      Class klass = employee.getClass();
      
      System.out.println( "Class name: " + klass.getName());
      System.out.println( "Class super class: " + klass.getSuperclass());
      
      int mods = klass.getModifiers();
      System.out.println( "Class is public: " + Modifier.isPublic(mods));
      System.out.println( "Class is final: " +  Modifier.isFinal(mods));
      System.out.println( "Class is abstract: " + Modifier.isAbstract(mods)); 
   }

}
코드를 실행하면 다음과 같은 결과를 확인할 수 있습니다.
Class name: com.russolsen.reflect.Employee
Class super class: class java.lang.Object
Class is public: true
Class is final: false
Class is abstract: false
예제에서 보이듯이 클래스의 이름과 상위 클래스를 알아내는 것은 다른 접근 메소드들(Getters or Accessors)을 호출하는 것처럼 쉬운 일입니다. 만약 해당 클래스가 public 인지 abstract 인지 final 인지 알고 싶다면 약간 복잡해 집니다. 이 모든 정보가 getModifires에 의해 하나의 int 값으로 패키징되어 넘어오기 옵니다. 다행히 Java는 Modifier 클래스를 통해 getModifiers에서 넘어온 숫자를 가지고 여러 일을 할 수 있는 static 메소드들을 제공해 줍니다.

객체에 getClass를 호출하는 것 만이 Class 객체를 얻을 수 있는 유일한 방법은 아닙니다. 클래스 이름을 사용하여 직접 얻을 수도 있습니다.
Class klass = Employee.class;
 
세 번째 방법은 좀 더 흥미로운 방법입니다. 문자열을 통해서 Class 객체를 생성할 수 있습니다. 물론 그 문자열이 클래스 이름을 포함하고 있을 때 말이죠. 다음과 같이 Class 클래스에 있는 forName 을 호출하여 얻을 수 있습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      
      System.out.println( "Class name: " + klass.getName());
      System.out.println( "Class super class: " + klass.getSuperclass());
      
      // Print out the rest...
forName을 사용할 때 한 가지 주의할 것은 클래스 이름 앞에 완전한 패키지 경로를 붙여줘야 한다는 것입니다. 평범하고 늙은 “Employee” 말고 “com.russolsen.reflect.Employee" 여야만 합니다. forName을 통해 리플렉션 API의 기본적인 강력함(그리고 멋진 것)을 살펴봤습니다. 클래스 이름을 포함한 문자열로 시작할 수도 있고 class로 끝낼 수도 있습니다.

바로 인스턴스 만들기

class 객체를 가져오고 그것에 관한 정보를 찾는 것은 그것 자체로도 흥미롭고 유용합니다. 하지만 진짜 재미있는 것은 리플렉션을 사용하여 무언가를 실제 해보는 것입니다. Class 객체를 가지고 할 수 있는 가장 눈에 띄는 작업은 그 클래스의 새로운 객체를 만드는 것입니다. newInstance 메소드를 사용하여 간단하게 만들 수 있습니다. 실제 사용하는 것을 보여 주기 위하여 아래에 있는 간단한 프로그램은 커맨드 라인 인자(command line argument)로 Class 객체를 만들고 그 클래스 타입의 객체를 만드는 프로그램을 보여줍니다.
package com.russolsen.reflect;

public class NewInstanceExample
{
   public static void main(String[] args)
      throws ClassNotFoundException,
      InstantiationException, IllegalAccessException
   {

      Class klass = Class.forName(args[0]);
      Object theNewObject = klass.newInstance();
      System.out.println("Just made: " + theNewObject);
   }
}
위 코드를 "com.russolsen.reflect.Employee" 인자와 함께 실행하면 새로운 Employee 객체를 만들게 됩니다.
Just made: Employee: John Smith 50000

Run it again, but this time feed it "java.util.Date" and you will get:

Just made: Tue Feb 27 20:25:20 EST 2007
간단한 코드 몇 줄로 얼마나 많은 유연성을 얻게 되었는지 생각해보세요. 위에 있는 프로그램은 실제 Employee 나 Date 클래스에 관해 아는 것이 하나도 없지만 각각의 새로운 객체들을 만들 수 있습니다. 이것이야 말로 Java 프로그래밍을 하는 또 다른 방법입니다.

인자 없는 생성자 너머에

Class.newInstance 메소드를 호출하는 것은 인자 없이 new를 사용하는 것과 동일합니다. 그러나 만약 인자가 없는 생성자 즉 default 생성자가 없는 클래스에 newInstance를 호출하면 어떻게 될까요? 좋을 일 없습니다. 별로 맘에 안 드는 InstantiationException을 받게 됩니다.

좋은 소식이 있습니다. 생성자 인자를 필요로 하는 클래스의 객체를 동적으로 만들 수 있습니다. 하지만 약간 더 힘든 작업을 해야 합니다. 그건 바로 클래스에서 해당 생성자를 찾고 적당한 인자를 사용하여 그것을 호출하는 일입니다. 적당한 생성자를 찾는 일은 여러분이 찾고자 하는 생성자에 대한 정보를 가지고 getConstrucor 메소드를 사용하면 됩니다. 그럼 Constuctor 객체를 얻게 되고 그것을 사용하여 새로운 객체를 만들 수 있습니다.
Let's see how this all works in code:
      Class klass = Class.forName("com.russolsen.reflect.Employee");

      Class[] paramTypes = {
            String.class, 
            String.class, 
            Integer.TYPE };
      
      Constructor cons = klass.getConstructor(paramTypes);
      
      System.out.println( "Found the constructor: " + cons);

      
      Object[] args = { 
            "Fred", 
            "Fintstone", 
            new Integer(90000) };
      
      Object theObject = cons.newInstance(args);
      System.out.println( "New object: " + theObject);
생성자들 사이의 차이점은 오직 그것들이 가지고 있는 매개 변수들입니다. 따라서 getConstructor 메소드에 찾고자 하는 생성자에 들어갈 매개변수 각각의 Class들 객체의 배열을 넘겨줍니다. 위에 있는 예제에서는 두 개의 String 그리고 하나의 int를 받는 생성자를 찾게 됩니다. Constructor 객체를 얻은 뒤 새로운 객체를 생성하는 일은 간단합니다. 실제 인자로 들어갈 객체의 배열을 newInstance 메소드를 호출하면서 넘겨주면 됩니다.

geConstructor에는 조그만 지뢰가 하나 있습니다. 파라미터의 타입으로 생성자를 식별하여 원하는 것을 찾을 때 primitive 인자와 그것의 wrapper 클래스를 잘 구별해야 합니다. 생성자가 인자로 primitive 타입인 int를 받는 것인가 아니면 그것의 삼촌 격인 java.lang.Integer 클래스의 객체를 받는 건가요? 만약 java.lang.integer 같은 wrapper 타입의 객체를 받는 생성자라면 Integer.class처럼 wrapper 클래스를 사용하면 됩니다. primitive 타입인 int를 사용하는 생성자라면 Integer.TYPE을 사용합니다. TYPE은 primitive을 위해 마련한 것입니다. 모든 wrapper 클래들은 static 타입인 TYPE 필드를 가지고 있고 이것을 사용하여 primitive 타입이라는 것을 알려줄 수 있습니다

----------------------------------------------------------------------------------

클래스를 좀 더 자세히 살펴보기

첫 번째 예제에서 봤듯이 Class 객체는 그것의 이름이나 상위 클래스 같은 정보를 제공합니다. 이 이름을 사용하여 좀 더 자세히 rank 와 시리얼 넘버(serial number) 차원의 정보까지 알 수 있습니다. 예를 들어 getMethods 메소드를 사용하여 클래스가 가진 모든 public 메소드를 찾을 수 있습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
           
      Method[] methods = klass.getMethods();
      
      for(Method m : methods )   {
         System.out.println( "Found a method: " + m );
      }
getMethods 는 클래스가 가지고 있는 public 메소드 각각에 해당하는 Method 객체의 배열을 반환합니다.
Found a method: public java.lang.String com.russolsen.reflect.Employee.toString()
Found a method: public int com.russolsen.reflect.Employee.getSalary()
Found a method: public void com.russolsen.reflect.Employee.setSalary(int)
Found a method: public native int java.lang.Object.hashCode()
Found a method: public final native java.lang.Class java.lang.Object.getClass()
Found a method: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
Found a method: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
Found a method: public final void java.lang.Object.wait() throws java.lang.InterruptedException
Found a method: public boolean java.lang.Object.equals(java.lang.Object)
Found a method: public java.lang.String java.lang.Object.toString()
Found a method: public final native void java.lang.Object.notify()
Found a method: public final native void java.lang.Object.notifyAll()
getMethods는 클래스의 사용자(client) 입장이기 때문에, 배열에는 자신이 가지고 있는 모든 public 메소드 (Object 까지 달하는 모든 상속 계층의 상위 클래스들에 있는 public 메소드까지 포함하여)를 배열에 담아 줍니다.

만약 하나의 메소드에만 관심이 있다면, getMethod(단수 형태 입니다.)를 사용할 수 있습니다. getConstructor와 비슷하게 동작하지만 파라미터 타입들 뿐만 아니라 메소드의 이름도 넘겨 줘야 합니다. 아래에 있는 코드는 하나의 int 파라미터를 가지는 setSalary 라는 메소드를 찾습니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      Class[] paramTypes = {Integer.TYPE };
      Method setSalaryMethod = 
         klass.getMethod("setSalary", paramTypes);
           
      System.out.println( "Found method: " + setSalaryMethod);
리플렉션을 사용하여 메소드를 호출하는 것은 constuctor를 호출하는 것과 매우 유사합니다. 앞서 살펴봤던 Method 객체만 있으면 되고 메소드에 인자로 넘겨 줄 배열과 메소드를 호출할 객체가 필요합니다. 아래에 있는 코드는 우리 직원에게 월급을 올려주기 위해서 Employee 객체에 있는 setSalary 메소드를 호출합니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");

      Class[] paramTypes = {Integer.TYPE };
      Method setSalaryMethod = 
         klass.getMethod("setSalary", paramTypes);
      
      Object theObject = klass.newInstance();
      Object[] parameters = { new Integer(90000) };
      
      setSalaryMethod.invoke(theObject, parameters);
그냥 theObject.setSalary(9000)를 호출하지 않고 왜 그렇게 귀찮게 했을까요? 위에 있는 코드를 자세히 살펴보시길 바랍니다. 코드의 첫 번째 줄을 빼면 위에 있는 프로그램은 완전히 일반적입니다. 어떤 클래스의 어떤 객체든 상관없이 setSalary 메소드를 호출할 것입니다. 약간만 수정하면 어떤 클래스의 어떤 객체든 거기에 있는 모든 메소드를 호출하는 코드로 사용할 수 있습니다.

필드 가지고 놀기

리플렉션을 사용하여 메소드를 호출하는 데에서 그치지 않습니다. 필드에 대한 모든 권한 역시 가지고 있습니다. getMethods 처럼 getFields는 해당 클래스 또는 그것의 상위 클래스에 있는 모든 public 필드 각각에 대한 Fileld 객체의 배열을 반환합니다.
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      System.out.println( "Class name: " + klass.getName());
      Field[] fields = klass.getFields();
      for(Field f : fields ){
         System.out.println( "Found field: " + f);
      }
Employee 가 두 개의 public 필드를 가지고 있기 때문에 두 개의 멤버를 가진 배열을 얻게 됩니다. 
Class name: com.russolsen.reflect.Employee
Found field: public java.lang.String com.russolsen.reflect.Employee._firstName
Found field: public java.lang.String com.russolsen.reflect.Employee._lastName
getField메소드를 사용하여 특정 필드 하나만 가져올 수도 있습니다.
      Field field = klass.getField("_firstName");
      System.out.println("Found field: " + field);
Field 객체를 가지고 get 메소드를 호출하면 필드가 가진 값을 가져올 수 있고 set을 사용하여 값을 설정할 수 있습니다.
      Object theObject = new Employee("Tom", "Smith", 25);
      
      Class klass = Class.forName("com.russolsen.reflect.Employee");
      
      Field field = klass.getField("_firstName");
      
      Object oldValue = field.get(theObject);
      System.out.println( "Old first name is: " + oldValue);
      
      field.set( theObject, "Harry");
      Object newValue = field.get(theObject);
      System.out.println( "New first name is: " + newValue);
위에 있는 코드를 실행하고 _firstName 필드가 변하는 것을 주의 깊게 살펴보시기 바랍니다.
Old first name is: Tom
New first name is: Harry
규칙 깨기

Java의 가장 신성한 규칙 중 하나를 깨는 방법을 얘기하지 않고서는 리플렉션을 마무리할 수 없습니다. 여러분 모두 잘 알다시피 해당 클래스 밖에서는 private 메소드를 호출 할 수 없습니다. 그렇죠? 아마 평범한 기술을 사용하는데 그친다면 하지 못할 것입니다. 하지만 리플렉션을 사용하면 거의 모든 걸 할 수 있습니다.

private 메소드를 호출하기 위해서 가장 먼저 해야 할 일은 호출하고 싶어 하는 메소드를 나타내는Method객체를 얻는 것입니다. getMethod로는 얻을 수 없습니다. 그건 오직 public 메소드만 반환합니다. private(또는 protected)메소드를 가져오는 방법은 getDeclaredMethod를 사용하는 것입니다. getMethod는 해당 클래스의 사용자 관점(client’s view)에서 public 메소드만 가져오지만, getDeclaredMethod는 클래스에 선언한 모든 메소드를 반환합니다. 아래에 있는 예제에서 java.util.ArrayList 클래스에 있는 private 메소드인 removeRange 를 가져옵니다.
      ArrayList list = new ArrayList();
      list.add("Larry");
      list.add("Moe");
      list.add("Curley");

      System.out.println("The list is: " + list);

      Class klass = list.getClass();

      Class[] paramTypes = { Integer.TYPE, Integer.TYPE };
      Method m = klass.getDeclaredMethod("removeRange", paramTypes);

      Object[] arguments = { new Integer(0), new Integer(2) };
      m.setAccessible(true);
      m.invoke(list, arguments);
      System.out.println("The new list is: " + list);
private 메소드를 받은 뒤에 간단히 setAccessable 안전장치를 제거하고 호출하면 됩니다.
The list is: [Larry, Moe, Curley]
The new list is: [Curley]
removeRange 메소드는 리스트에서 주어진 범위의 아이템을 제거하는 것처럼 보입니다. 이것은 매우 강력한 마술입니다. java.util 에 있는 클래스에 접근하여 그 안에 있는 private 메소드를 호출할 수 있습니다. 이것을 사용하여 코드의 의도를 우회하여 private 메소드를 호출하는 취미를 즐기실 건가요? 아니죠! 그러나 저런 것들이 약간은 유용할 때가 있습니다.

결론

리플렉션을 사용하여 Java의 규칙을 무시하는 것처럼 보이는 것들을 하는 프로그램을 작성할 수 있습니다. 일반적으로는 알 수 없는 클래스에 관한 정보를 모두 알아내는 코드를 작성할 수 있습니다. 그리고 동적으로 알아낸 정보에 어떤 행위를 할 수도 있습니다. 즉 새로운 객체를 만들고 메소드를 호출하고 필드에 값을 설정하거나 가져올 수 있습니다. 극단적인 경우에서는 클래스의 private 멤버들에 접근할 수 있습니다. 점점 복잡해져가는 Java 개발 툴의 동작을 이해하기 위해서는 리플렉션에 대한 이해가 필요합니다. 또한 “평범한” Java 프로그램이 할 수 있는 것 이상의 프로그램을 작성해야 할 때도 필요합니다.


제공 : 한빛 네트워크
저자 : Russ Olsen
역자 : 백기선
원문 : Reflections on Java Reflection

'I.lib() > I.lib(Java)' 카테고리의 다른 글

Heapdump 파일 생성 이유  (0) 2010.05.19
JNDI 란?  (1) 2010.04.08
자바의 abstract와 인터페이스(Interface)  (0) 2010.03.24
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
.
:
Posted by .07274.
2010. 3. 26. 21:47

24일차 I.edu()/I.edu(S&S)2010. 3. 26. 21:47

.. .. ..
* 7~8시
- Java 규칙
  + Compling    <- jvm
  + onload  -> static , implements , abstract,
  + runtime

- AOP 하는 이유.
              + 공통 모듈을 만들기 위해..
*8~9시
           - java -(Xms,Xmx,Xss,Xloggc)를 사용하여 메모리 등의 제어를 한다.
           - Spring AOP ing

*9~10시
           - AOP ing
           - non fix된 String 이나 int 값들은 static final 로 미리 지정해 둔다.
             + 이유는 후에 메모리에 올릴시에 자원의 소모량이 처음에 메모리에 올릴때보다 많기 때문이다.
             + function 에서도 변경되지 않는 데이터가 있을시에는 final을 붙여준다.
           - throw e 와 new throw e 의 차이는?? 
           
- reflection 이란?!
- jdk의 src에 reflection 패키지 열어보고 분석.
 
 

'I.edu() > I.edu(S&S)' 카테고리의 다른 글

26일 (Final)  (0) 2010.03.30
25일차  (0) 2010.03.29
23일차  (1) 2010.03.25
22일차  (0) 2010.03.24
21일차  (0) 2010.03.23
.
:
Posted by .07274.
2010. 3. 26. 10:30

AOP 용어 I.lib()/I.lib(Spring)2010. 3. 26. 10:30

.. .. ..

'I.lib() > I.lib(Spring)' 카테고리의 다른 글

Spring Annotation (스프링 어노테이션)  (1) 2010.04.06
Spring 트랜잭션 격리 수준, 전달 행위의 값  (0) 2010.04.02
Spring ppt 모음  (1) 2010.03.24
Spring Tutorial  (0) 2010.03.24
Spring - JPetStore[1]  (0) 2010.03.16
.
:
Posted by .07274.
2010. 3. 25. 21:48

23일차 I.edu()/I.edu(S&S)2010. 3. 25. 21:48

.. .. ..

*7~8시
-review

*8~9시
- Sample source 분석

*9~10시
- Spring 이용 통신 모듈 실루엣 (각각의 Object 추출 후 공통 모듈 수집후 Process 방법 결정.)
 - chap1.01
- JDBC Driver는 크게 4가지 Type으로 나누어 진다.
  • Type 1 : JDBC-ODBC Bridge Driver
  • Type 2 : Native-API Driver : OCI Driver (Partle Java Driver) 
  • Type 3 : Net-Protocol Driver (All Java Driver)
  • Type 4 : Native-Protocol Driver(thin Driver) 

                                                                      ↑
                                                                  추가내용.
      - private static final String serialversionuid   <-- 클레스의 식별 ID ( 클레스 꼬일시 대비해서 만들어짐)












 

'I.edu() > I.edu(S&S)' 카테고리의 다른 글

25일차  (0) 2010.03.29
24일차  (1) 2010.03.26
22일차  (0) 2010.03.24
21일차  (0) 2010.03.23
20일차  (1) 2010.03.22
.
:
Posted by .07274.
2010. 3. 24. 22:00

22일차 I.edu()/I.edu(S&S)2010. 3. 24. 22:00

.. .. ..

*7~8시
-
 Class  interface  abstract
 New New (X)   New (X)
 Single inheritance (extends) multi inheritance (implements)  Single inheritance
 1  2
     추상클레스
      final(O), static(X)


*8~9시
            - 자바 파일관련 코딩시 주의할 점
              + 디렉토리 이름은 띄어쓰기 하면 안된다.
              + 파일이름, 디렉토리 이름의 길이는 꼭(must) 제한한다. 
           
+ 디렉토리 이름은 대소문자를 정확하게 써야 한다.
          
+ 디렉토리 (패키지) 단계는 가능하면 되도록 짧게 쓰기
              + 상대경로, 절대경로는 코딩으로 대체한다. (자동 컨버젼 될수 있도록 한다.)

*9~10시
           - Spring Sample Source

 
 
 

'I.edu() > I.edu(S&S)' 카테고리의 다른 글

24일차  (1) 2010.03.26
23일차  (1) 2010.03.25
21일차  (0) 2010.03.23
20일차  (1) 2010.03.22
19일차  (0) 2010.03.19
.
:
Posted by .07274.
.. .. ..

1> abstract 키워드란?

하위 클래스에서 반드시 오버라이딩(재정의)를 해줘야만 하는 키워드이다.
메서드와 클래스에만 쓸수 있다.

2> abstract 특징

  1. 클래스와 메서드에만 사용 가능.
  2. 메서드에서는 프로타입(선언부)만 정의, 내용(구현부)은 없다.
  3. abstract 은 final, static과 같이 쓸순없다.

3> abstract 클래스 인경우

  1. 미완성 클래스(추상메서드가 포함된 클래스는 자동으로 추상클래스가 됨)
  2. 추상클래스는 추상메서드를 포함 가능(반드시 포함해야 하는 것은 아님)
  3. 구조상 상속해서 재정의해야만 사용 가능
  4. 자체적으로 객체를 생성할 수 없음
  5. 하위클래스에서 추상메서드를 반드시 구현(오버라이딩)해야 함
  6. 형식>>> abstract class 클래스명 {.......}

4> abstract 메서드 인경우

  1. 메서드의 원형만 선언된 메서드 : 블록({})이 없는 메서드
  2. 하위 클래스에서 반드시 오버라이딩해야함.
  3. 추상메서드를 포함하는 클래스는 반드시 추상클래스
  4. 형식>>> abstract 반환형 메서드명 (인자);

5> abstract 클래스 vs abstract 메서드

  • 추상메서드를 포함하는 클래스는 반드시 추상클래스
    -- 클래스에 abstract를 표시하지 않으면 에러
  • 추상클래스는 추상메서드를 포함 가능
    -- 반드시 포함해야 하는 것은 아님
  • 하위클래스에서 상속 받은 추상메서드를 반드시 재정의해야 함




▶ 인터페이스(Interface)

 1> 인터페이스(Interface)란?

 자바에서는 다중상속(여러 클래스로부터의 동시상속)을 금지하고 있다. 이 덕분에 명확한 상속관계가 유지되지만 필요에 따라 다중 상속이 필요할 때도 있다.이런 경우를 위해서 인터페이스라는 개념이 도입되었다. 즉, 인터페이스는 다중상속을 허용해 준다.
나중에 살펴볼 이벤트에서 인터페이스를 사용하므로 반드시 개념을 이해한다.

1. 객체모델링을 통한 클래스 구성

만약 tv, 오디오, 카메라를 클래스로 작성한다고 하자. 이 세가지에는 리모컨이라는 기능이 공통적으로 가지고 있으나 서로의 기능은 다르다. 따라서 상속을 한다면 다중상속이 되지 않기 때문에 각기 따로 클래스를 작성해서 상속을 해야한다. 그러면 코딩도 많아지고 불편할 것이다. 

2. 인터페이스를 통한 클래스 구성

다중상속이 허용되는 인터페이스를 사용하는 경우 리모컨 인터페이스를 선언해서 각 클래스에서 구현해서(인터페이스를 사용하는 것은 상속이라 하지 않고 '구현'이라 한다.) 각각의 클래스에 맞게 새롭게 내용만을 정의해 주면 된다. 이는 특히 공동작업을 하는 프로그램에서 통일된 코드를 작성할 수 있다.

2> 인터페이스 특징

  1. 클래스와 메서드 선언만 하고 내용은 없다.
  2. 인터페이스 사용시 반드시 하위 클래스는 인터페이스를 오버라이딩 해야한다.
  3. 인터페이스는 자동적으로 다음과 같이 된다.
    멤버 변수 : public final static
    메서드 : public abstract
  4. 구현을 위해 implements 키워드 사용.
    예> class 클래스명 implements 인터페이스1, 인터페이스2, 인터페이스3...{....}
  5. 다중 상속이 가능 . ,(콤마)를 구분으로 여러개 의 인터페이스를 상속가능.
  6. 인터페이스 끼리 상속 가능. 이때는 extends 키워드 사용.



 



 

'I.lib() > I.lib(Java)' 카테고리의 다른 글

JNDI 란?  (1) 2010.04.08
자바 리플랙션 (Java Reflection)  (1) 2010.03.29
Javap 란? (자바 역어셈블러)  (1) 2010.03.24
POJO (Plain Old Java Object) 란?  (0) 2010.03.23
클레스 어샘블리. (Class -> Java )변환  (1) 2010.03.05
.
:
Posted by .07274.