레이블이 프로그래밍(Programming)인 게시물을 표시합니다. 모든 게시물 표시
레이블이 프로그래밍(Programming)인 게시물을 표시합니다. 모든 게시물 표시

2016년 7월 4일 월요일

spring + spring-data-jpa + hybernate + postgresql 설정

1. pom.xml 에 dependency 추가

- spring-data-jpa, hybernate, postgresql 관련 dependency 만 표기하겠음.

      org.springframework.data
      spring-data-jpa
      1.10.2.RELEASE
  
  
      org.hibernate.javax.persistence
      hibernate-jpa-2.0-api
   1.0.1.Final
  
  
      org.hibernate
      hibernate-core
      5.1.0.Final
  
  
      org.hibernate
      hibernate-entitymanager
      5.1.0.Final
  
  
      org.hibernate
      hibernate-ehcache
      5.1.0.Final
  
  
      postgresql
      postgresql
      8.4-702.jdbc4
  


2. context-datasource.xml 파일에 설정 추가

 - 종료태그 부분이 구글 블로그에서 이상하게 번역되는데... <property name=
"dasdf" value="adfs" /> 이렇게 끝나야 하고... 뒤에 덧붙여진거 지워야함;;;;

      
 
   
    
        
        
        
        
    
    
    
    
    
        
        
            
        
    
    
    
        
        
        
            
                
                
                
                
            
        
        
            
                hibernate.cache.use_second_level_cache = true
                hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory
                hibernate.cache.use_query_cache = true
                hibernate.generate_statistics = true
            
        
    



3. DAO Interface 설정

 * TestDAO (Interface 만 있어도 CrudRepository 를 이용하면 기본적인 CRUD 가능)

import org.springframework.data.repository.CrudRepository;

import moo.vo.Test;

public interface TestDAO extends CrudRepository{

}

* TestService

package moo.service;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import moo.dao.TestDAO;
import moo.vo.Test;

@Service
public class TestService {
 
 @Inject
 TestDAO testDAO;
 
 public void saveTest(Test test){
  testDAO.save(test);
 }
 
 public Test getTest(int id){
  
  return testDAO.findOne(id);
 }
 
 public Iterable getTests(){
  return testDAO.findAll();
 }
}

* Test (VO 파일)

package moo.vo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity
public class Test {
 @Id
 @GeneratedValue
 private int id;
 
 private String contents;

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getContents() {
  return contents;
 }

 public void setContents(String contents) {
  this.contents = contents;
 }
}




끝! 

2013년 9월 6일 금요일

Spring Security - 한 유저 동시 접속 막기

Spring Security - 한 유저 동시 접속 막기




만약 한명의 유저가 여러번 로그인하는 것을 막고 싶다면 아래와 같이 설정한다.

먼저 web.xml 에 listener를 등록한다.

<listener>
    <listener-class>
      org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
  </listener>

다음으로 Application Context에 아래 태그를 추가한다.

  <http>
    ...
    <session-management>
        <concurrency-control max-sessions="1" />
    </session-management>
  </http>


이렇게 하면 두번째 로그인 시 먼저 로그인한 것은 무효화된다.

만약 나중에 로그인 한 것을 막고 싶다면 아래와 같이 설정한다.

  <http>
    ...
    <session-management>
        <concurrency-control max-sessions="1" error-if-maximum-exceeded="true" />
    </session-management>
  </http>


이러한 설정으로 인해 거부된 사용자는 form-based login방식이 쓰여지고 있다면 authentication-failure-url 로 보내지게 되는데, 그렇지 않다면 402에러와 같은 내용이 사용자에게 전달된다. 만약 에러페이지를 설정하고 싶다면, session-management 요소에 session-authentication-error-url 속성을 추가하면 된다.

2013년 5월 7일 화요일

IP 주소로 해당 실제 지역(국가,도시) 를 찾아주는 API, MAXMIND

www.maxmind.com

무료 javascript api를 제공해주고, 또 csv 나 binary 로 된 database 도 제공해준다!

좀더 강력한 기능이나, 꾸준한 업데이트를 받고 싶다면 구입해야 하지만...

이정도만 되도 충분히 사용할 거 같다. 좋네...



무료로 제공하는 메서드는 아래 표에서 위에 두개만 쓸수있다.

API

After the geoip2.js script is imported, you will have the geoip2 module in your namespace. This module provides four functions:
FunctionDescription
geoip2.country(onSuccess, onError, options)Calls the GeoIP2 Country endpoint using the routable IP address associated with the machine on which it is running.
geoip2.city(onSuccess, onError, options)Calls the GeoIP2 Precision City endpoint using the routable IP address associated with the machine on which it is running.
geoip2.cityISPOrg(onSuccess, onError, options)Calls the GeoIP2 Precision City/ISP/Org endpoint using the routable IP address associated with the machine on which it is running. Only available to paying customers.
geoip2.omni(onSuccess, onError, options)Calls the GeoIP2 Precision Omni endpoint using the routable IP address associated with the machine on which it is running. Only available to paying customers.

Sample Code

<script type="text/javascript" src="//j.maxmind.com/js/geoip2.js"></script>

<script type="text/javascript">

var onSuccess = function(location){
    alert(
        "Lookup successful:\n\n"
        + JSON.stringify(location, undefined, 4)
    );
};

var onError = function(error){
    alert(
        "Error:\n\n"
        + JSON.stringify(error, undefined, 4)
    );
};

geoip2.city(onSuccess, onError);

</script>

Sample Object

The following is an example of a JavaScript object passed to the successCallback.
{
  "country": {
    "iso_code": "KR",
    "names": {
      "zh-CN": "韩国",
      "en": "South Korea",
      "ja": "大韓民国",
      "ru": "Южная Корея"
    },
    "geoname_id": 1835841
  },
  "city": {
    "names": {
      "en": "Seoul",
      "ja": "ソウル特別市",
      "ru": "Сеул"
    },
    "geoname_id": 1835848
  },
  "subdivisions": [
    {
      "iso_code": "11",
      "names": {
        "en": "Seoul"
      },
      "geoname_id": 1835847
    },
    {
      "iso_code": "11",
      "names": {
        "en": "Seoul"
      },
      "geoname_id": 1835847
    }
  ],
  "location": {
    "longitude": "126.977969",
    "latitude": "37.566535",
    "time_zone": "Asia/Seoul"
  },
  "continent": {
    "names": {
      "zh-CN": "亚洲",
      "en": "Asia",
      "ja": "アジア",
      "ru": "Азия"
    },
    "continent_code": "AS",
    "geoname_id": 6255147
  },
  "traits": {
    "ip_address": "152.99.241.12"
  },
  "registered_country": {
    "iso_code": "KR",
    "names": {
      "en": "South Korea",
      "zh-CN": "韩国",
      "ja": "大韓民国",
      "ru": "Южная Корея"
    },
    "geoname_id": 1835841
  },
  "postal": {},
  "represented_country": {
    "names": {}
  }
}



Maxmind 를 무료로 쓰기위해서는 도메인 등록만하면 된다.

자 이제 ㄱㄱ



2013년 2월 18일 월요일

Log4j 설정


로그4J 라이브러리 임포트 과정은 생략함니다.

로그4J가 import된 프로젝트의 Src 폴더에 아래와같은 파일을 생성함니다

log4j.properties

이제 log4j가 업무를 수행할때 해당 파일에 들어있는 환경변수들을 사용하여 출력 함니다.

log4j.properties 파일 내부데이터로 들어가겠습니다.

먼저 출력 객체의 선언 임니다.

두가지 객체 선언 방법이 있습니다.
log4j.rootLogger        
log4j.logger.

전자의 경우 rootLogger로서 해당 프로젝트내에서 발생하는 로그업무를 모두 출력 합니다.
(레벨별 제한은 물론 함니다.)

후자의 경우 logger 뒤에 '.' 가 있는데. 해당 프로젝트내의 특정 패키지를 계속 이어붙임니다.
ex) log4j.logger.baeseulki.seul 

이렇게하면 저 패키지에서 일어나는 로그업무에 대해서만 처리함니다.

객체선언의 마지막 할당 입니다.

log4j.rootLogger               =     debug, hoho, haha
log4j.logger.baeseulki.seul      =      info, seul, kikiki

오른쪽에 1번째 변수는 출력해줄 경보레벨의 제한임니다. 
info의 경우 debug.info.warn.err.fatal 에서 debug는 출력되지 않습니다.

2번째 이상부터는 객체 명임니다. 아래에서 객체명을 통해서 로그의 출력방법, 출력 형식등을 설정함니다.

즉 현재 루트로거에는 hoho와 haha방식으로 출력한다고 보면 되겠습니다.

두방법 다 사용하면
두방법다 객체에 지정한 방법대로 출력함니다. 이제 출력 객체 설정에 들어감니다.


출력 객체로의 접근방법은 다음과 같습니다.

log4j.appender.객체명.객체의 속성값 = 속성에 적용할 값

객체명은 hoho , seul, 과 같이 우리가 생성한 객체입니다.
속성값은 file 같이 정해진 특정 속성입니다.
file 속성은 출력할 파일명을 말함니다. 
ex) log4j.appender.hoho.file = c/log/hoho.log

일단 객체의 출력 방법부터 설정합시다. 출력 방법의 경우 속성값이 없습니다. 객체 자체에 넣습니다.

og4j.appender.객체명 = 출력방식

출력방식은 정해진 값들이 있습니다.
org.apache.log4j.ConsoleAppender     //콘솔창에 출력
org.apache.log4j.DailyRollingFileAppender       //파일에 출력

ex)  log4j.appender.hoho = org.apache.log4j.DailyRollingFileAppender


layout 속성은 출력한 스타일을 표현함니다. 2중으로 사용함니다.
일반적인 PatternLayout을 사용함니다.

세부적인 내용은  layout.ConversionPattern 에 추가로 설정합니다.
아래와같이 함니다.

log4j.appender.hoho.layout=org.apache.log4j.PatternLayout
log4j.appender.hoho.layout.ConversionPattern=[%d] %-5p %l - %m%n

아래 패턴에 들어가는 내용은 프로그램상에서
private static Logger logger = Logger.getLogger(seul.class); 
logger.debug("슬슬");

여기 들어간 슬슬 이라는 출력 내용을 ConversionPattern 의 형태로 변경하여 출력 함니다.
Pattern의 %? 값들의 내용은 다음과 같습니다.

%p : 호출명(ex DEBUG, INFO, WARN, ERROR, FATAL)
%n : 줄바꿈
%m : 매개변수 메세지
%t : 스레드
%F : 실행파일명
%M : 수행 메소드
%L : 라인????넘버
%d : 날짜


log4j.appender.hoho.DatePattern='.'yyyy-MM-dd
// 매일 자정에 로그파일을 교체하며 기존파일은 xx.log_2004.07.12 

log4j.appender.hoho.Threshold=DEBUG
//출력할 정보의 최소단위.


소스

log4j.rootLogger = info, stdout, dailyfile 

log4j.stdout = false
log4j.debug = false

log4j.appender.stdout = org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d] HIHI- %m%n

log4j.appender.dailyfile.Threshold = ERROR
log4j.appender.dailyfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyfile.File = c:\\log\\logfile.log 
log4j.appender.dailyfile.layout = org.apache.log4j.PatternLayout
log4j.appender.dailyfile.layout.ConversionPattern=%5p ({%t} %F[%M]:%L) [%d]  - %m%n

log4j.appender.dailyfile.DatePattern ='.'yyyy-MM-dd


log4j.logger.log4j.bae=DEBUG, BAE
 
log4j.appender.BAE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.BAE.File=C:/logs/BAE.log
log4j.appender.BAE.DatePattern='.'yyyy-MM-dd
log4j.appender.BAE.Threshold=DEBUG
log4j.appender.BAE.layout=org.apache.log4j.PatternLayout
log4j.appender.BAE.layout.ConversionPattern=[%d] %-5p %l - %m%n

log4j.logger.log4j.hehe=INFO, HEHE
 
log4j.appender.HEHE=org.apache.log4j.DailyRollingFileAppender
log4j.appender.HEHE.File=C:/logs/HEHE.log
log4j.appender.HEHE.DatePattern='.'yyyy-MM-dd
log4j.appender.HEHE.Threshold=DEBUG
log4j.appender.HEHE.layout=org.apache.log4j.PatternLayout
log4j.appender.HEHE.layout.ConversionPattern=[%d] %-5p %l - %m%n

---------------------------------------------------------
출처 - http://blog.naver.com/skykingkjs?Redirect=Log&logNo=150152227953

쉘 프로그래밍 기초


쉘 프로그래밍 강좌


1. 변수
  . 쉘변수는 처음 사용될때 만들어진다. 즉 미리 선언할 필요가 없다.
  . 쉘변수는 유닉스 명령과 마찬가지로 대소문자에 구별이 있다.
  . 쉘변수는 기본적으로 데이터를 문자열로 저장한다. 수치를 대입해도 실제 수치
    가 아닌 문자열이 저장된다. 계산이 필요할 경우는 자동으로 수치로 변환하여 
    계산후 다시 문자열로저장된다.
  . 쉘변수의 값을 사용할 때는 변수명앞에 "$" 를 붙여서 사용한다.
  . 쉘변수에 값을 대입할때는 "$"를 사용하지 않는다.
  . 쉘변수는 타입이 없다. 즉 아무 값이나 다 넣을 수 있다.
 
1.1 환경변수
  쉘을 기동하고나면 기본적으로 셋팅되어있는 변수들이다. 유닉스/리눅스에는 많은
  환경변수들이 있고 필요한경우 이 변수들을 마치 일반변수처럼 값을 얻어오거나 셋
  팅할 수 있다. 여기서는 쉘과 직접적인 관련이 있는것만 설명한다. 
  
  $0 - 실행된 쉘 스크립트 이름
  $# - 스크립트에 넘겨진 인자의 갯수
  $$ - 쉘 스크립트의 프로세스 ID
  
1.2 인자 변수
  쉘스크립트에 인자를 넘겨줄때 그 인자들에 대한 정보를 가지고 있는 변수들.
  
  $1~ $nnn  : 넘겨진 인자들
  $*        : 스크립트에 전달된 인자들을 모아놓은 문자열. 하나의 변수에 저장되며
              IFS 환경변수의 첫번째 문자로 구분된다.
  $@        : $*과 같다. 다만 구분자가 IFS변수의 영향을 받지 않는다.
 
1.3 일반변수
  일반변수에 특별한 제약은 없다. 단 대소문자 구분만 정확하게 해주면 된다.

  예제 )

  #!/bin/sh
  echo "This Script Executable File : $0"
  echo "Argument Count : $#"
  echo "Process ID : $$"
  echo "Argument List \$* : $*"
  echo "Argument List \$@ : $@"
  echo "Argument 1 : $1"
  echo "Argument 2 : $2"
  echo "Argument 3 : $3"
  echo "Argument 4 : $4" 
   
  실행 )
  $chmod 755 test1
  $./test1 a1 a2 a3 a4
  This Script Executable File : ./test1
  Argument Count : 4
  Process ID : 905
  Argument List $* : a1 a2 a3 a4
  Argument List $@ : a1 a2 a3 a4
  Argument 1 : a1
  Argument 2 : a2
  Argument 3 : a3
  Argument 4 : a4
 
1.4 연산
  변수의 산술연산은 생각하는것 처럼 쉽지않다. 위에서 언급했듯이 변수에는 모든것
  이 문자열로 저장되기 때문에 연산이 불가능하다. 연산을 위해서는 좀 복잡한 절차
  를 거쳐야 한다.

  변수 = $((산술식))
 
  이것이 가장 단순한 연산 규칙이다. 산술식내에는 변수( $1, $a 와 같은 ) 도 들어
  갈 수 있다. 산술식 내에 숫자가 아닌 문자열, 또는 문자열이 담겨있는 변수가 들어
  가면 그것들은 계산에서 제외된다.
  (정확히 말하면 0 으로 간주되어 연산이 이루어 지지 않는다.)
 
1.5 매개변수 확장
  매개변수 확장이란 변수의 값을 문자열등으로 대체하는 것을 말한다. 단순한 대체뿐
  아니라 변수내의 문자열을 조작하여 원하는 문자열만을 추출할 수도 있다.

  형식
  ${parm:-default} : parm이 존재하지 않으면 default로 대체된다.
  ${#parm}          : parm의 길이를 참조한다.(가져온다)
  ${parm%word}      : 끝에서부터 word와 일치하는 parm의 최소부분(첫번째 일치) 을
                      제거하고 나머지를 반환한다.
  ${parm%%word}     : 끝에서부터 word와 일치하는 parm의 최대부분(마지막 일치) 을
                      제거하고 나머지를 반환한다.
  ${parm#word}      : 처음부터 word와 맞는 parm의 최소부분(첫번째 일치)을 제거하
                      고 나머지 부분을 반환한다.
  ${parm##word}     : 처음부터 word와 맞는 parm의 최대부분(마지막 일치)을 제거하
                      고 나머지를 반환한다.
  
  * word에는 와일드 카드를 사용할 수 있다.
  
  예를 보자.
    
  1 #!/bin/sh
  2
  3 p="/usr/X11R6/bin/startx"
  4
  5 unset p
  6 a=${p:-"Variable p Not found"}
  7 echo $a
  8
  9 p="/usr/X11R6/bin/startx"
  10 a=${p:-"Variable parm Not found"}
  11 echo $a
  12
  13 a=${#p}
  14 echo $a
  15
  16 a=${p%/*}
  17 echo $a
  18
  19 a=${p%%/*}
  20 echo $a
  21
  22 a=${p#*/}
  23 echo $a
  24
  25 a=${p##*/}
  26 echo $a
  27                    
  
  위 스크립트의 결과는 다음과 같다.
  ---------------------------------
  Variable p Not found
  /usr/X11R6/bin/startx
  21
  /usr/X11R6/bin
  
  usr/X11R6/bin/startx
  startx              
  ----------------------------------
   6행 : 변수 p 가 제거 되었으므로 "Variable p Not found" 가 a에 들어간다.
  10행 : 변수 p 가 있으므로 그대로 a에 들어간다.
  13행 : a에는 변수 p의 길이가 들어간다.
  16행 : p 에서 가장 오른쪽의 "/"부터 끝까지 지우고 나머지를 a에 넣는다.
  19행 : p 에서 가장 왼쪽의 "/" 부터 끝까지 지우고 나머지를 a에 넣는다.
         (아무것도 없다)
  22행 : p 의 처음부터 가장왼쪽의 "/" 까지 지우고 나머지를 a에 넣는다.
  25행 : p 의 처음부터 가장 오른쪽의 "/"까지 지우고 나머지를 a에 넣는다.
  
2. 조건 판단
  쉘 스크립트에서 조건판단은 if 와 test 명령을 혼합하여 사용한다.
  일반적인 예는 다음과 같다.
 
  if test -f test1
  then
   ...
  fi
  
  -f 는 주어진 인자가 일반파일 일때 참이된다.
  
  
  test 명령은  [] 로 대체될 수 있다.
  
  if [ -f test1 ]
  then
   ...
  fi
  
  -----------------------------
  
  if [ -f test1 ]; then
   ...
  fi
 
  2.1 test 명령
  
  test 명령의 조건은 다음과 같이 세 부류로 나누어진다.
 
  문자열비교
    [ string ]             : string이 빈 문자열이 아니라면 참
    [ string1 = string2 ]  : 두 문자열이 같다면 참
    [ string1 != string2 ] : 두 문자열이 다르면 참
    [ -n string ]          : 문자열이 null(빈 문자열) 이 아니라면 참
    [ -z string ]          : 문자열이 null(빈 문자열) 이라면 참
  
  산술비교
    [ expr1 -eq expr2 ] : 두 표현식 값이 같다면 참 ( EQual )
    [ expr1 -ne expr2 ] : 두 표현식 갑이 같지 않다면 참 ( Not Equal )
    [ expr1 -gt expr2 ] : expr1 > expr2 이면 참 ( Greater Then )
    [ expr1 -ge expr2 ] : expr1 >= expr2 이면 참 ( Greater Equal )
    [ expr1 -lt expr2 ] : expr1 < expr2 이면 참 ( Less Then )
    [ expr1 -le expr2 ] : expr1 <= expr2 이면 참 ( Less Equal )
    [ ! expr ]          : expr 이 참이면 거짓, 거짓이면 참
    [ expr1 -a expr2 ]  : expr1 AND expr2 의 결과 ( 둘다 참이면 참 )
    [ expr1 -o expr2 ]  : expr1 OR expr2 의 결과 ( 둘중 하나만 참이면 참 )
  
  파일조건

    [ -b FILE ]           : FILE 이 블럭 디바이스 이면 참
    [ -c FILE ]           : FILE 이 문자 디바이스 이면 참.
    [ -d FILE ]           : FILE 이 디렉토리이면 참
    [ -e FILE ]           : FILE 이 존재하면 참
    [ -f FILE ]           : FILE 이 존재하고 정규파일이면 참
    [ -g FILE ]           : FILE 이 set-group-id 파일이면 참
    [ -h FILE ]           : FILE 이 심볼릭 링크이면 참
    [ -L FILE ]           : FILE 이 심볼릭 링크이면 참
    [ -k FILE ]           : FILE 이 Sticky bit 가 셋팅되어 있으면 참
    [ -p FILE ]           : True if file is a named pipe.
    [ -r FILE ]           : 현재 사용자가 읽을 수 있는 파일이면 참
    [ -s FILE ]           : 파일이 비어있지 않으면 참
    [ -S FILE ]           : 소켓 디바이스이면 참
    [ -t FD   ]           : FD 가 열려진 터미널이면 참
    [ -u FILE ]           : FILE 이 set-user-id 파일이면 참
    [ -w FILE ]           : 현재 사용자가 쓸 수 있는 파일(writable file) 이면 참
    [ -x FILE ]           : 현재사용자가 실행할 수 있는 파일(Executable file) 이면 참
    [ -O FILE ]           : FILE 의 소유자가 현재 사용자이면 참
    [ -G FILE ]           : FILE 의 그룹이 현재 사용자의 그룹과 같으면 참
    [ FILE1 -nt FILE2 ]   : FILE1이 FILE2 보다 새로운 파일이면 ( 최근파일이면 ) 참
    [ FILE1 -ot FILE2 ]   : FILE1이 FILE2 보다 오래된 파일이면 참
    [ FILE1 -ef FILE2 ]   : FILE1 이 FILE2의 하드링크 파일이면 참
  
  2.2 if 구문
    if 문은 조건을 판단하여 주어진 문장을 수행한다.
  
    1. 형식 1  ( 단일 if 문 )
    형식 :
      if [ 조건 ]
      then
        문장1
        문장2
      fi
    
    2. 형식 2  ( if~else 문 )
    형식 :
      if [ 조건 ]
      then
        문장3
        문장4
      fi
    
    3. 형식 3  ( if~elif 문 )
    형식 :
      if [ 조건 ]
      then
        문장1
        문장2
      elif
        문장3
        문장4
      else
        문장5
        문장6
      fi
    
  2.3 case 구문
  ※ 패턴에는 * 문자, 즉 와일드카드를 사용할 수 있다.
  형식 :
      case 변수 in
        패턴 [ | 패턴 ] ... ) 문장 ;;
        패턴 [ | 패턴 ] ... ) 문장 ;;
        ....
        * ) 문장 ;;
      easc
  
  2.4 목록
    여려명령을 실행할때 앞의 명령의 결과에 의해서 다음행동이 결정되어야 할 경우
    가 있다. 이런경우에 AND나 OR조건을 사용해서 한번에 처리할 수 있다. 이것은 쉘
    스크립트 뿐 아니라 명령행에서도 사용 가능하다. 물론 if 문을 이용해서 반환값
    을 검사하여 처리할 수 있지만 문장이 길어지고 복잡해진다.
  
    AND 목록
 
        statment1 && statment2 && statmentN && .....

        위의 명령들은 각 명령이 거짓이 될 때 까지 명령을 수행해 나간다. 수행도중
        결과가 거짓이 되면 그이후의 명령은 수행되지 않는다.
 
    OR  목록
 
        statment1 || statment2 || statmentN || .....
 
        위의 명령들은 각 명령이 거짓이 나오는 동안 계속된다. 즉 참이 나오면 실행
        을 멈춘다.
 
    AND와 OR목록은 혼용이 가능하다.
 
        [ 조건 ] && 문장1 || 문장2

        위의 예는 조건이 참이면 문장1을 수행하고 거짓이면 문장2를 수행한다.

        또한 위의 문장1이나 문장2에서 여러개의 문장을 수행 하고 싶을 때는 {}를
        사용하면 된다.

        [조건] && {
                    문장1
                    문장2
                    문장3
                          } || {
                                 문장4
                                 문장5
                                 문장6
                               }
 
3. 제어문
  3.1 for
  for 문은 지정된 범위안에서 루프를 수행한다. 범위는 어떤 집합도 가능하다.
  형식 :
         for 변수 in 값1, 값2, ...
         do
             문장
         done

  매 루프를 돌때마다 변수의 값은 in 이후의 값으로 대체된다.
  예)
      for str in "test1", "test2", "test3", "test4"
      do
         echo @str
      done

  출력 )

      test1
      test2
      test3
      test4
  
  값에는 와일드 카드 확장을 사용할 수 있다.

    for file in $(ls -a | grep "^.")
    do
      echo "$file is Hidden File"
    done

  위 예의 출력 결과는 현재디렉토리에서 처음이 "." 으로시작하는 파일(히든파일) 만
  을 출력한다.

  for file in $(ls chap[345].txt); do
      echo "--- $file ---" >> Books.txt
      cat $file >> Books.txt
  done

  위의예는 chap3.txt, chap4.txt, chap5.txt 파일을 Books.txt 라는 파일에 붙여 넣
  는다.

  다음의 예를 보고 결과를 예측해보자

  echo "\$* output"

  for fvar in $*
  do
    echo $fvar
  done

  echo "\$@ output"
  for fvar in $@
  do
    echo $fvar
  done
    
  3.2 while
    for 명령의 경우는 횟수를 지정해서 루프를 수행하는데는 문제가 있다.
    while 문은 실행횟수가 지정되지 않았을때 편리하다.
  
    형식 :
           while 조건문
           do
                문장
           done
   
    예제를 보자. 패스워드를 입력받고 맞는지 확인하는 프로그램이다.

    echo "Enter Password : "
    read password1

    echo "Retype Password : "
    read password2

    while [ "$password1" != "$password2" ]
    do
         echo "Password miss match Try again "

         echo "Retype Password : "
         read password2
    done

    echo "OK Password Match complete"
  


    어떻게 동작하는가 ?
    
  3.3 until
    until은 while문과 동일한 효과를 내지만 조건이 반대이다. 즉, while문은 조건이
    참 일동안 루프를 수행하지만 until은 조건이 거짓일 동안 루프를 수행한다.
    
    형식 :
      until 조건문
      do
       문장
      done
    
    다음 예를 보자. 이 예는 지정한 유저가 로그인 하면 알려준다.
    
    #!/bin/sh
    
    until who | grep "$1" > /dev/null
    do
        sleep 10
    done
    
    echo "User $1 just logged in ^_^"
  
 3.4 select
    select 문은 원하는 리스트를 출력하고 그중 선택된것을 돌려주는 구문이다. 주의
    할점은 select의 루프내에서는 자동적으로 루프를 벗어날 수 없다. 반드시 break
    문을 사용해서 루프를 벗어나야 한다.
  
    예) 간단한 퀴즈 ^_^

      #!/bin/sh
      
      echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?"
      select var in "쉘 프로그래밍" "C 프로그래밍" "자바 프로그래밍" "Exit"
      do
          if [ "$var" = "쉘 프로그래밍" ]
          then
                  echo "정답입니다."
                  exit 0
          elif [ "$var" = "Exit" ]
          then
                  echo "종료합니다."
                  exit 1
          else
                  echo "$var 을 선택하셨습니다. 오답입니다."
                  echo "다음중 스크립트언어 프로그래밍에 속하는 것은 ?"
          fi
      done

4. 함수
  쉘 스크립트 내부에 또는 다른 스크립트파일에 함수를 정의해 놓고 사용할 수 있다.
  함수를 사용하면 코드를 최적화 할 수 있고, 코딩이 간결해지며,재사용이 가능하다.
  그러나 다른 스크립트 파일을 호출해서 함수를 실행할 경우, 가능은 하지만 스크립
  트의 실행시간이 길어지고, 함수의 결과를 전달하는 것이 까다롭기 때문에 가급적이
  면 외부파일의 함수는 안쓰는 것이 좋다.
 
  형식 :
    정의 - 
    함수명 ()
    {
     문장
     return 값
    }
    
    사용
    
    함수명 인자1, 인자2, ...
    
    
    함수는 독립적으로 $#, $*, $0 등의 인자변수를 사용한다. 즉 함수내의 $#과 본체
    의 $#은 다를 수 있다는 것이다.
    
    다음의 예를 보자
    
    #!/bin/sh
  
    func()
    {
      echo ------ this is func --------
      echo "This Script Executable File : $0"
      echo "Argument Count : $#"
      echo "Process ID : $$"
      echo "Argument List \$* : $*"
      echo "Argument List \$@ : $@"
      echo "Argument 1 : $1"
      echo "Argument 2 : $2"
      echo "Argument 3 : $3"
    }
  
    echo ------ this is main --------
    echo "This Script Executable File : $0"
    echo "Argument Count : $#"
    echo "Process ID : $$"
    echo "Argument List \$* : $*"
    echo "Argument List \$@ : $@"
    echo "Argument 1 : $1"
    echo "Argument 2 : $2"
    echo "Argument 3 : $3"
    echo "Argument 4 : $4"
    func aa bb cc 


    본체와 함수에서 동일한 변수를 보여주지만 값은 틀린다는것을 알 수 있다.
    
    함수에서 값을 반환하기 - 함수에서 반환값은 반드시 정수값만을 반환할 수 있다.
    이 값을 if등으로 조건을 판단해서 사용할 수 있다. 반환값중 0은 참으로 나머지 
    숫자는 거짓으로 판별된다.
  
5. 명령어
  쉘에서 쓸 수 있는 명령어는 두가지로 나누어진다. 명프롬프트 상에서 실행 시킬 수
  있는 외부 명령어와 쉘 내부 명령이다. 내부명령은 보통 쉘 내부나 쉘 구문상에서
  쓰인다. 외부명령은 쉘에 관계없이 사용이 가능하다.
 
  break
    제어문이나 조건문의 루프를 빠져나갈때 사용한다.
    예)
     while [ $a -eq 10 ]
     do
      if [ $a -eq 5 ]; then
       break
      fi
     done
 
  :명령
    의미없는 명령. 논리값 true를 대신해 쓰기도 한다.
  
  continue
    제어문이나 조건문의 처음으로 돌아가서 다시수행한다.
    예)
     while [ $a -eq 10 ]
     do
         if [ $a -eq 5 ]; then
               continue
            fi
     done
  
  . 명령
    . 명령을 사용하면 현재 쉘에서 명령을 실행시킨다 그러므로 실행된 명령의 결과
    를 본 프로그램에서 사용할 수 있다.
    
    예를 들면 A 라는 스크립트에서 B라는 스크립트를 그냥 실행할 경우 B에서의 변화
    (환경변수 등)는 A에게 아무런 영향도 미치지 않는다. 그러나 . 명령을 사용해서 
    실행하면 B에서의 변화가 A에도 영향을 미친다.
  
  echo
    문장을 출력한다. 자동으로 개행문자가 삽입된다. ( 다음줄로 넘어간다 )
 
  eval
    인자의 실제 값을 구하는데 사용한다.
  
    foo=10
    x=foo
    y='$'$x
    echo $y
  
    이 예를 실행해 보면 $foo가 출력된다
  
    foo=10
    x=foo
    eval y='$'$x
    echo $y
  
    이 예에서는 $foo의 값 즉 10 이 출력된다. eval명령은 원하는 문자열들을 조합해
    서 변수를 액세스 할 수 있다.
 
  exec
    현재쉘을 다른 프로그램으로 대체한다.
  
    예 ) exec csh
 
  exit n
    현재 쉘을 종료한다. 종료시 n 값을 리턴한다.
 
  export
    해당 쉘에서 파생된 자식 프로세스에서 export한 환경변수는 본래 쉘에서 관리한
    다.
 
  expr
    표현식의 값을 구한다.    ( x=`expr 1 + 2` )
    요즘은 expr보다는 $((계산식)) 구문을 많이 사용한다.
 
  printf
    C 언어의 printf명령과 흡사하다.
    
    형식 :  printf "Format String" arg1 arg2 arg3 ...
  
  return
    쉘함수에서 값을 반환 할 때 쓰인다.
    0은 성공을 1~125까지는 쉘 에러코드를 나타낸다.
 
  set
    쉘 내부에서 매개 인자를 설정한다.
    set의 인자로 쓰인 문자열은 공백에 의해 $1 부터 차례대로 대입된다.
    
    예)
    
    #!/bin/sh
    echo $#
    set $(ls)
    echo $# 
    
    결과는 
    
    0
    22
    
    이다..( 22는 필자의 ls 결과의 갯수이다. ). 첫번째 0는 이 스크립트에 인수가
    없으므로 0이고 set $(ls) 에 의해서 인수의 갯수가 22개로 늘었다.
 
  shift
    쉘의 인자를 한자리씩 아래로( n -> 1 로 ) 이동시킨다.
    
    예)
    #!/bin/sh
    
    echo $1
    shift
    echo $1
    shift 5
    echo $1
    
    #./myscript 1 2 3 4 5 6 7 8 9 0
    1
    2
    7
 
 trap
    쉘의 실행도중 시그널을 처리하는 시그널 처리기를 만드는 역할을 한다.
    
    형식 : trap command signal
    
    쉘 스크립트는 위에서 아래로 실행되므로 보호하려는 부분 이전에 trap명령을 사
    용해야 한다. trap조건을 기본으로 사용하려면 명령에 - 를 넣으면 된다.
    신호를 무시하려면 '' 빈 문자열을 준다.
 
  unset
   변수나 함수를 제거한다.

6. 명령실행
  외부명령의 실행 결과를 변수에 집어넣어 변수의 값으로 사용할 수 있다.
  
  형식 : x = $(명령)
  
  이렇게 변수에 결과를 넣은 후에는 이 변수를 일반문자열로 생각하고 원하는 가공을
  해서 결과를 얻어낼 수 있다.
  위에서 보았던 매개변수 확장이나 set명령을 이용해서 원하는 부분을 추출해 내면
  그만이다.

7. 쉘 스크립트 내부에서 명령에 입력 전달하기 ( Here Documents )
  이 기능은 쉘 내부에서 명령어에 입력을 전달하는 방법이다. 전달된 입력은 마치 키
  보드에서 눌려진 것 처럼 반응한다.
  
  형식 :  명령 << 종료문자열
    입력값.....
    종료문자열
  예제 ) 자동으로 메일을 보내는 스크립트
  
  #!/bin/sh
  
  mail $1 << myscript
  This is Header
  This is Body
  .
  
  myscript

-------------------------------------
출처 - http://blog.naver.com/wonie777?Redirect=Log&logNo=120000890723
[출처] 쉘 프로그래밍|작성자 워니

2013년 1월 28일 월요일

Java에서 volatile 이란??



Java Language Specification 에 나온 내용을 기반으로 설명함.



8.3.1.4 volatile Fields


The Java programming language allows threads to access shared variables (§17.1).
As a rule, to ensure that shared variables are consistently and reliably updated, a
thread should ensure that it has exclusive use of such variables by obtaining a lock
that, conventionally, enforces mutual exclusion for those shared variables.
The Java programming language provides a second mechanism, volatile fields,
that is more convenient than locking for some purposes.
A field may be declared volatile, in which case the Java Memory Model ensures
that all threads see a consistent value for the variable (§17.4).8.3.1 Field Modifiers CLASSES

It is a compile-time error if a final variable is also declared volatile.



일단 위를 번역, 의역해보자..



자바는 thread 들이 공유된 변수에 접근하는 것을 허용한다.
일반적으로는(Java 뿐 아닌 다른 언어에 대해서도), Thread 간에 공유된 변수들의 일관성 있고 확실한 업데이트(데이터의 변경)를 하기 위해,

thread 는 이러한 변수들을 독점적으로 얻기 위한 방법으로 mutex 를 적용하곤 했다.

(여러 Thread 가 같은 변수에 한번에 접근하지 않기 위해서 Mutual Exclusion 처리를 해주고 있다는 말임.)


자바에서는 이에대해 좀더 쉬운 방법인 volatile field 라는 또 다른 방식을 제공한다.
field 가 volatile 을 이용해서 선언이 되었을 경우에,

자바 메모리 모델은 해당 변수에 대해 모든 쓰레드가 일관된 값을 사용할 것을 보장한다.
만약에 final 과 volatile 혼용해서 쓴다면 컴파일 시점에 오류가 발생하게 된다.



좀더 자세히 살펴보자..



1. Thread 간에 변수가 공유되면, Thread 는 그 값을 복사해 놓은 후, 복사한 값을 참조해서 사용한다.


Java 에서는 Thread 를 사용할 때 performance 향상을 위해 해당 변수의 값을

Thread 가 사용하는 메모리 영역에 caching 하는 것을 허용한다.


예를 들면, ThreadA 와 ThreadB 라는 두개의 쓰레드가 foo 라는 변수를 바라보고 있을 때,

foo 라는 변수를 각각 쓰레드의 로컬 메모리영역에 caching 해서 사용을 하는 식이 된다.


따라서, ThreadA 가 foo 라는 변수의 값을 "abc" 에서 "def" 로 바꾼다고 하더라도

어느 시점에는 ThreadB 는 여전히 "abc" 라는 값을 가지고 있을 수 있다.

(간단한 테스트 코드로도 확인 가능하다.)



이러한 문제를 극복하기 위해 volatile 이라는 키워드를 사용해서 변수를 선언하게 되면,

각 Thread 들은 foo를 caching 하지 않고, foo를 사용할 때마다 메인메모리 영역의 foo 를 바라본다.


위 글을 읽다 보면 final 과 volatile 은 같이 사용이 불가능 하다는 구문이 나오는데,

내 생각에는 final 은 변수가 바뀌지 않는다는 것을 전제도 하는 키워드이지만,

volatile 은 변수가 바뀌는 것을 전제로 하는 키워드이기 때문에 둘을 혼용해서 쓸 수 없는 것 같다.

2. Thread 간에 공유된 변수에 한 Thread 가 접근하면, 다른 Thread 는 접근하지 못한다.



예를들면 4바이트 이상의 변수인 long 을 변경한다고 했을 때, 앞 4바이트와 뒤 4바이트를 나눠서 변경한다.

예를들면 long 값을 21521542 에서 463634110 으로 변경시킨다고 했을 때, 앞 4바이트를 변경하고 뒤 4바이트를 변경한다.



이게 어떤 결과를 야기시킬 수 있냐면,

여러 ThreadA 가 long 값을 변경시키고 있는 와중에도 ThreadB 가 long 에 접근하면,

ThreadB 는 21521542 도 아니고 463634110 도 아닌 전혀 다른 값을 출력할 수 있다는 얘기다.



그 값의 정체는 앞4바이트 값은 바뀌고 있는데 뒤 4바이트는 예전의 값인, 두 숫자가 혼합된 값이 나올수도 있다는 얘기다.

(int 같은 경우에는 어차피 4바이트 변수니까 해당사항이 없긴 하다.)



내가 알아본 volatile 키워드의 효과는 위에 적은 두가지다.

까먹지 말고 잘 사용합시다~ :)

--------------------------------
출처 - http://maruldy.tistory.com/43

2012년 12월 4일 화요일

모바일 브라우저에서 글 내용에 따라 자동으로 늘어나는 textarea 만들기


제가 앞에 작성한 “모바일 브라우저에서 글 내용에 따라 자동으로 늘어나는 textarea 만들기” 는 글을 작성한 만큼 textarea의 크기가 늘어납니다. 하지만 작성한 글을 지워서 내용이 줄어들었을 때 textarea의 크기는 줄어들지 않고 계속 커진 상태로 남아 있습니다.
이점을 수정해서 글 내용이 많아질 때는 textarea의 크기가 커지고 글 내용이 줄어들었을 때는 textarea의 크기도 작아지도록 만들어봤습니다. 이것을 구현하기 위해 어떻게 해야할지 생각이 잘 안떠올랐는데 검색을 해보니 구현하신 분이 있어서 그 분의 아이디어를 그대로 가져와서 만들었습니다. 그 분의 글은 http://james.padolsey.com/javascript/jquery-plugin-autoresize/ 입니다.
textarea의 크기를 늘리는 기능은, 글 내용이 길어지면 textarea의 scrollHeight 값이 커지기 때문에 이 크기에 따라 textarea의 높이(height)를 조절해 주는 방식으로 만들수 있었지만 textarea의 크기를 줄이는 기능은 이 방법을 사용할 수 없었습니다. textarea의 높이가 글 내용 높이보다 작아서 스크롤바가 생기는 상황이라면 글 내용의 많고 적음에 따라 scrollHeight 값이 변하지만, 이미 textarea의 높이를 글 내용이 많아졌을 때에 맞게 늘렸었기 때문에 이 상태에서 글자를 지워서 글 내용 높이를 줄여도 scrollHeight의 값은 변하지 않게 되어 textarea 높이를 글 내용 높이에 맞게 줄여줄 기준값으로 사용할 수 없게 되기 때문입니다.
이 것을 해결하기 위해 제가 참고한 http://james.padolsey.com/javascript/jquery-plugin-autoresize/ 에서는 textarea의 clone을 만드는 방법을 사용하고 있었습니다. clone으로 만든 textarea는 사용자에게는 안보이도록 positin:absolute; top:0; left:-9999; 처리를 한 다음 사용자에게 보이는 진짜 textarea에 글씨가 입력될 때마다 clone textarea에도 그대로 글이 입력되게 합니다. 그리고 진짜 textarea의 높이 조절을 clone textarea의 scrollHeight 값을 가지고 조절하는 방식입니다.
(그런데 제가 참고한 사이트에서 clone을 사용한다는 아이디어만 참고하고 나머지 코드는 참고를 안해서 제가 만든 버전은 오류가 좀 있을 수도 있을 것 같습니다.)
제가 말씀으로 설명드려서 좀 복잡한데 소스코드를 보시면 이해가 되실 것 같습니다.
  1. // textarea의 id가 textarea인 경우를 가정해서 #textarea 사용
  2. (function() {
  3.  
  4. var textarea = $('#textarea'),
  5. originHeight = textarea.height(),
  6. originClientHeight = textarea[0].clientHeight,
  7. clone = textarea.clone(),
  8. extraHeight = parseInt(textarea.css('fontSize')),
  9. timer, content, cloneScrollHeight;
  10.  
  11. clone
  12. .removeAttr('id')
  13. .removeAttr('name')
  14. .css({
  15. position: 'absolute',
  16. top: 0,
  17. left: -9999,
  18. overflow: 'hidden'
  19. }).appendTo('body');
  20.  
  21. textarea.focus(function() {
  22.  
  23. timer = setInterval(function() {
  24. content = textarea.val();
  25. clone.val(content);
  26. cloneScrollHeight = clone[0].scrollHeight;
  27.  
  28. if (originClientHeight < cloneScrollHeight) {
  29. textarea.css('height', cloneScrollHeight + extraHeight);
  30. } else if (originClientHeight === cloneScrollHeight) {
  31. textarea.css('height', originHeight);
  32. }
  33. }, 100);
  34.  
  35. });
  36.  
  37. textarea.blur(function() {
  38. clearInterval(timer);
  39. });
  40.  
  41. })();
데모를 http://codefactory.kr/lab/autogrowshrink_textarea.html 에 올려놓았습니다. 필요하신 분은 한번 확인해보세요..^^

모바일 웹(Mobile Web) a href 속성, input type 속성, 북마크아이콘 추가 방법


모바일 웹에서 바탕화면 아이콘 추가소스

<link rel="apple-touch-icon" href="이미지경로.png" />
 바탕화면으로 북마크 추가할때 생기는 이미지


모바일웹 Href 태그속성들

- 전화걸기 : <a href="tel:1588-1234">오라인포 고개센터</a>
- 문자보내기 : <a href="sms:010-1234-5678">문자보내기</a>
- 문자보내기 실행 : <a href="sms:">문자보내기</a>
- 메일보내기 실행 : <a href="mailto:">메일보내기</a>
- 메일보내기 : <a href="mailto:test@test.co.kr">메일보내기</a>
- 내용 채워서 메일 보내기
<a href="mailto:test@test.co.kr?cc=test@test.co.kr&bcc=test@test.co.kr&subject=test
subject&body=test body"">메일보내기</a>


모바일 Input type 속성

<input type="text" /> 기본적인 모바일 키보드가 제공됩니다.
<input type="password" /> 기본적인 모바일 키보드가 제공됩니다.
<input type="email" /> 기본적인 모바일 키보드 + @ / . 제공됩니다.
<input type="tel" /> 기본적인 숫자 모바일 키보드가 제공됩니다.
<input type="url" /> 기본적인 모바일 키보드 + / + . + .com 이 제공됩니다 .
<input type="search" /> 기본적인 숫자 모바일 키보드가 제공됩니다 go 부분이 Search로 변경됩니다.



참고 : http://blog.naver.com/jjjhyeok/20150492216

2012년 10월 17일 수요일

자바, 접근자의 종류(Access Level)


private : 해당 멤버를 선언한 클래스 내부에서만 접근할 수 있다.

package-private (default) : 해당 멤버를 선언한 클래스와 이 클래스와 같은 패키지에 있는 모든 클래스에서 접근할 수 있다. 접근 수정자를 붙이지 않으면 정해지는 접근 수준이므로 기본 접근이라고도 한다.

protected : 해당 멤버를 선언한 클래스, 이 클래스의 하위 클래스, 이 클래스와 같은 패키지에 있는 모든 클래스에서 접근할 수 있다.

public : 모든 클래스에서 접근할 수 있다.

2012년 9월 26일 수요일

쓰레드(Thread)

<생성방법>

1. Thead 클래스의 상속


Class ThreadClass extends Thread {
    public void run(){ 
        System.out.println("쓰레드가 실행되었습니다");     
    }
}

Class ThreadTest {

  public static void main(String[] args){
     ThreadClass threadClass = new ThreadClass();
     threadClass.start();
     //start하면 쓰레드에게 cpu가 할당되었을때 run()이 실행된다
  }
}

2. Runnable 인터페이스 구현


Class RunnableClass implements Runnable {
    public void run(){ 
        System.out.println("쓰레드가 실행되었습니다");     
    }
}

Class ThreadTest {

  public static void main(String[] args){
     Runnable runnableClass = new RunnableClass();
     Thread thread = new Thread(runnableClass);
     thread.start();
  }

}

* 상속을 이용한 Thread 클래스는 다른 클래스를 상속할 수 없지만(이미 쓰레드를 상속하고있기 때문에, 인터페이스를 구현한 Runnable 클래스는 다른 클래스를 상속할 수 있다.


<생성자>


1. Thread()
2. Thread(String s)
3. Thread(Runnable r)
4. Thread(Runnable r, String s)

s : 쓰레드 이름
r  : Runnable Interface를 구현한 Class


<메소드>

1. static void sleep(long msec) : 
  msec에 지정된 밀리초 동안 대기

2. static void sleep(long msec, int nsec) : 
    msec에 지정된 밀리초 + nsec에 지정된 나노초 동안 대기

3. String getName() : 
    스레드의 이름을 반환

4. void setName(String s) : 
스레드의 이름을 s로 설정

5. void start() : 
스레드를 시작시킨다. run() 메소드를 호출

6. final int getPriority() : 
스레드의 우선순위를 반환

7. final void setPriority(int p) : 
스레드의 우선순위를 p 값으로 설정

8. boolean isAlive() : 
스레드가 실행 가능 상태, 실행상태, 대기상태에 있으면 true를 그렇지 않으면 false를 반환

9. void join() throws InterruptedException : 
스레드가 끝날 때까지 대기

10. void run() : 
스레드가 실행할 부분을 기술하는 메소드, 하위 클래스에서 오버라이딩 되어야 한다.

11. void suspend() : 
스레드가 일시 정지된다. resume()에 의해 다시 시작될 수 있다.

12. void resume() : 
일시 정지된 스레드를 다시 시작시킨다.


이외에는 JAVA API 의 Thread 클래스 참조.
 - JAVA7 API : http://docs.oracle.com/javase/7/docs/api/ 

<생명 주기>


1. 쓰레드 객체가 생성되면 쓰레드는 메모리에 올라간다.

2. start() 메소드가 호출되면 실행가능 상태가 된다.(cpu 할당대기)

3. cpu가 할당되면 run() 메소드를 실행하며 실행상태가 된다.

4. cpu할당 시간이 종료되거나, yield() 함수가 실행되면 다시 실행가능 상태로 변한다.

5. sleep(), join(), 입출력 등을 요구하게되면 쓰레드는 대기상태로 전환되고, sleep time이 말료되거나, join() 할 쓰레드가 종료, 입출력 종료, notify(), notifyAll() 메소드가 호출되었을시에 실행가능 상태로 전환한다.

6. 해당 쓰레드의 코드가 모두 실행되었을 경우에는 종료된다.




2012년 9월 7일 금요일

Service Locator Pattern


J2EE 규약은 다른 리소스나 서비스들에 대한 접근을 JNDI에 위임한다. J2EE 호환 서버는 이런한 리소스나 서비스들을 JNDI 서버에 바인드함으로써 클라이언트가 네트워크의 어디에도 JNDI lookup 프로세스를 통해 리소스나 서비스들을 lookup 할수 있도록 한다이러한 리소스나 서비스의 종류는 EJBHome, DateSource, JMS ConnectionFactory, JMS Topic/Queue 등이 있다이러한 요소들의 객체는 JNDI API를 사용하여 얻어진다. JNDI 룩업을 수행하여 어떻게 벤더에서 다른 벤터로 변경하는 것이 가능할까? JNDI 룩업 수행의 반복은 시스템의 부하를 줄수 있다.

JNDI로부터 서비스를 호출해야 할 때 매번 사용자가 적절한 JNDI 서버에 연결하고, JNDI 환경 정보를 알아내어 서비스를 찾는다필요한 것은 JNDI로부터 다양한 서비스를 생성 하고 가져올수 있다는 단일점이다여기에서 Service Locator 패턴이 사용된다.

Service Locator 패턴은 단순하게 사용할 수 있는 인터페이스로 모든 JNDI 룩업방식을 추상화 한다사용자가 특정한 EJB JDBC… 연결을 요청할 때 데이터 소스에 연결하려고 처음 생성했던 JDBC 커넥션 객체를 재사용하고, EJBHome 인터페이스를 케싱함으로써 JNDI 룩업의 호출 횟수를 최소화한다.

2012년 9월 6일 목요일

Javascript의 Function의 속성 및 메서드

# 개요  

자바스크립트에서 제일 중요한 요소는 함수입니다.
흔히 일급 객체 (first-class-object) 라고 불리는 자바스크립트 함수는 자바스크립트에서 거의 모든 것을 할 수 있습니다. 보통 언어에서 흔히 지원되는 함수의 동작인 실행, 값의 반환같은것은 당연하게 수행하며, 자신이 반환값이 되기도 하고 인자로서 넘겨지기도 하며, 객체의 프로퍼티나 변수 할당도 가능합니다.

심지어 변수 스코프 경계를 짓거나, new 연산자와 쓰여 다른 객체를 생성하는 생성자 역할 및 클로저로서도 동작하는 그야말로 만능 엔터테이너입니다.

그리고 많은 분들이 재미있어(?) 하시는 prototype 속성을 가진 객체이기도 합니다.

함수는 어떤 속성과 메서드를 갖는지 한번 알아봅시다. 


함수의 속성들 

자바스크립트에서는 함수도 엄연한 Object이기에 속성을 가지고 프로그래머가 임의로 정의할 수도 있습니다. 또한 기본으로 여러 속성을 가지고 있기도 합니다.

그런 것들은 대부분 Function이라는 빌트인 함수의 프로토타입에서 상속된 것입니다.

arguments
함수가 실행될 때 바인딩되는 늦은 바인딩 변수입니다.
함수가 생성되었을 당시에는 null 값을 가지고 있습니다. 런타임이 굉장히 중요한 함수죠.

유사 배열 객체(array-like object)로서 함수가 실행되었을 때 전달되어 초기화된 인자를 순서대로 0번 인덱스부터 첨자로 하여 배열 형식으로 가지고 있습니다. 
function javarouka() {
    // 인자를 따로 선언하지 않아도 런타임시 주어진 인자로 초기화됩니다.
    // 그리고 배열과 같은 기능을 하는 속성 length가 있습니다.
    for(var i=0; i < arguments.length; i++) {
        console.log(i + "째 인자의 값은 " + arguments[i]);
    }
    // false. 배열이 아닙니다.
    console.log (arguments instanceof Array)               
}
console.log(javarouka.arguments) // 실행 전에는 null 입니다.
javarouka("hello", "javascript", "function", "property!"); // 잘 출력되겠죠?
절대 배열로 착각하여 arguments.push() 나 arguments.slice() 같은 배열 메서드를 사용하지 마세요. 만일 사용하고 싶다면
Array.prototype.push.call(arguments, "밀어넣을 요소");
var aryArgs = Array.prototype.slice.call(arguments); // 진짜 인자 배열 얻기
형식으로 배열의 함수를 컨텍스트만 자신으로 바꿔서 사용하면 됩니다.
또한 실행중인 자기 자신을 참조하는 callee 속성도 눈여겨 볼만 합니다. 
var i = 0;
(function() {
    if(i < 10) {
        document.writeln(i++);
        // arguments.callee은 자기 자신을 참조하는 속성입니다.
        setTimeout(arguments.callee, 100);
    }
})();
// 0123456789 가 출력될 겁니다
혹자는 이 arguments 속성이 자바스크립트에서 함수 호출의 유연함을 강조한다고 하지만 개인적으로는 혼돈에 빠뜨리는 속성이라고 생각합니다.
MDN에서는 이 속성을 Deprecated 로 정의하고 있지만, 기존 소스에서 사용되는 빈도가 높아 없어지진 않을 것 같습니다.

length
함수 생성시 지정한 받을 인자의 개수를 나타냅니다.
대다수의 브라우저에서 지원합니다. 하지만 경험상 막상 쓸일이 그리 없었던 듯 합니다. 
function nonblock(val1, val2) {
    /* 뭔가 열심히 하는 로직 */
}
console.log(nonblock.length) // 2
주의할 점이 있는데, arguments.length의 값과는 다를 수 있습니다.
이쪽은 선언적인 인자의 숫자이며, arguments.length는 실행시 인자의 숫자입니다.

constructor
Object에서 상속받은 속성입니다. 자신을 생성한 함수를 가르킵니다.
일반적으로 콘솔이나 alert등으로 출력을 시도할 경우 네이티브 함수의 toString() 값인 function Function() { [native code] } 을 볼 수 있을 것입니다.
실제 반환되는건 Function 객체입니다. 
function Niceguy() {
    /* ...이런저런 구현... */
}
// Niceguy 라는 함수객체는 네이티브코드에서 생성됩니다
console.log(Niceguy instanceof Function) // true.
console.log(Niceguy.constructor) // function Function() { [native code] }

// 반면, 생성자로 쓰일 경우 생성된 객체의 constructor가 됩니다.
var javarouka = new Niceguy();
console.log(javarouka.constructor) // Niceguy
caller
자신을 실행시킨 함수를 반환하는 비표준 속성입니다.
만일 속성값이 null이라면 글로벌 컨텍스트에서 실행한 것입니다.

다음 예제를 보세요. 
var obj = {
    a: function() {
        return obj.a.caller;
    },
    b: function(f) {
        return f();
    }
}
obj.a(); // null
obj.b(obj.a); // obj.b 반환. toString()은 function (f) { return f(); } 가 됩니다.
name
함수의 이름을 반환하지만 이 경우 반드시 함수 선언문으로 한 경우에만 반환됩니다.
비표준이며, IE는 지원하지 않습니다.

(2012-02-17 추가) 

함수 선언문 뿐 아니라 이름을 가진 함수 리터럴(named function-literal) 일 경우에도 name 속성이 나오는군요. 이때 함수가 할당된 변수가 name이 되는게 아닌 함수 리터럴에 지정한 이름이 name이 됩니다. 
// 함수 선언문
function func1() { /* ... */ }
func1.name // "func1"

// 함수 표현식 변수할당
var func2 = function() { /* ... */ }
func2.name // "" ( or undefined or null? )

// 이름을 가진 함수 표현식
var func3 = function myFunc() { /* ... */ }
func3.name // "myFunc"

prototype
함수(내장함수도 물론 포함합니다)만이 가지고 있는 속성으로 자바스크립트 객체지향의 근간입니다. 이것만 왜 붉은 색이냐 하면 그만큼 중요하기 때문입니다.

설명은 기존의 포스트를 참고해 주세요
http://blog.javarouka.me/2011/12/prototype-property-and-prototype-chain.html 


함수의 메서드들

함수도 객체이기에 메서드들을 가질 수 있습니다.
보통 함수에 사용자가 뭔가를 정의할일은 거의 없습니다. 라이브러리 레벨의 범용성을 추가할 때 사용되는게 대부분입니다.

아래 소개할 함수 대부분도 call이나 apply등을 빼면, 고급 기능에서나 사용될 법 한 것들입니다.

apply(컨텍스트 [, 인자의 배열 ])
call(컨텍스트 [, 인자1, 인자2....])
기능이 같으므로 함께 설명합니다.
이 메서드를 사용하면 함수를 실행시키는 컨텍스트를 직접 지정할 수 있습니다. 쉽게 말하면 this변수에 연결될 객체를 선택할 수 있습니다.

apply, call 둘다 첫번째 인자는 활성 객체이며 두번째 인자부터만 다릅니다.
apply는 함수를 실행할 인자를 배열 형식으로 절달하며, call은 인자를 하나하나 나열하는 식이죠.
첫번째 컨텍스트를 전달하지 않거나 null을 주게 되면 글로벌 컨텍스트로 지정됩니다.

다음의 예제를 보세요. 
function Computer(name, price) {    
    this.name = name;
    this.price = price;  
}
function Notebook(name, price) {
    // 호출 객체를 현재 생성될 객체로 지정합니다.
    Computer.apply(this, arguments);
    this.type = "portable";
}

var vaio = new Notebook("VAIO", 2250000);

vaio.name // "VAIO"
vaio.price // 2250000
vaio.type // "portable"
위의 Notebook 함수를 생성자로 써서 만든 객체 vaio는 생성자에서 Computer를 호출함으로써 name과 price를 자신의 속성으로 지정할 수 있지요.

보통은 저런 용도로 쓰진 않지만요...

bind(컨텍스트 [, 인자1, 인자2....])
위의 call, apply와 비슷하지만 이번에는 주체가 함수가 됩니다.
함수의 스코프 체인과 프로토타입을 첫번째 인자의 것으로 모두 바꾸고 나머지 인자를 함수에 전달하여 실행합니다.

말로 하니 복잡한데 예제를 봅시다. 
var name = "Lee";
var other = {
    name: "Kim"
}
function getName() {
    return this.name;
}
getName() // 전역 참조. 결과는 "Lee"

var wasBound = getName.bind(other);
wasBound(); // 바인드 된 객체 참조. 결과는 "Kim"
함수를 특정 객체의 스코프 체인에 묶어버리는(bind) 기능입니다.
아직은 크롬과 파이어폭스에서만 지원됩니다.

toString
Object에서 상속한 메서드로서 본래 기능은 해당 값의 문자열 형식을 반환하게 되어 있습니다. 대부분의 자바스크립트 엔진 구현에서는 함수의 toString을 호출하면 함수 소스코드의 내용이 나옵니다. 네이티브 코드로 구현된 부분은 소스코드의 내용이 공개되지 않습니다.

문자열 결합 연산자 (+) 나 alert, document.write() 등의 인자가 되거나 해서 문자열이 필요한 경우 자동으로 호출되어 연산됩니다. 
function javarouka() {
    /* 뭔가 한다 */
}
// toString을 override
javarouka.toString = function() {
    return "Happty Programer";
}
// 문맥상 문자열 연산이 필요할 때 자동으로 호출됩니다
console.log("블로그의 주인은 " + javarouka + "입니다");
valueOf
역시 Object에서 상속된 메서드로서 값의 원시값(primitive value) 값을 반환하게 되어 있습니다. 역시 대부분의 엔진에서는 함수 자체를 그대로 반환합니다.
-, /, * 등의 산술 연산에 함수를 직접 쓸 경우 자동으로 호출됩니다.

혹시라도 함수로 숫자 연산을 하고 싶다면 오버라이딩 해 두면 덧셈뺄셈등의 연산이 가능해 집니다. (그런데 그럴 일이 있을지 모르겠습니다) 
function one(i18n) {
    if(i18n === "ko") return "하나";
    else if(i18n === "jp") return "いち";
    return "one";
}
one.valueOf = function () { return 1; }

// 원시 값 연산이 필요한 경우 자동으로 호출됩니다.
var result = 38 - one;
console.log(result) // 37
toSource
함수의 소스코드를 문자열로 반환합니다. 대부분의 경우 toString과 결과가 같습니다.




------------------------------------------------------
출처 - http://blog.javarouka.me/2012/02/javascript-function.html