자바·JSP2012. 9. 3. 13:32

오랜만에 토비 스프링을 다시 보다가 Class.forName(String value)이라는 구문이 눈에 들어왔고..


평소에는 그냥 아 이렇게 쓰는거구나하고 넘겼는데..이게 뭔지 갑자기 궁금해졌다.


그래서 찾아보니..


forName을 하게 되면 해당 클래스를 동적 로드하게 되는데..이 때는 생성자는 실행하지 않고


static 필드 부분만 실행하게 된다.


고로 "com.oracle.jdbc.OracleDriver" 이 클래스 안에는 static { 솰라솰라} 가 있을테고

DriverManager 안에도 static으로 driver 멤버 변수가 선언되어 있을 것이며, OracleDriver가 로드 될 때

 

DriverManger안에 세팅을 해주는 방식으로 구현이 되어있다. 이제 궁금점이 풀렸군..

'자바·JSP' 카테고리의 다른 글

JAVA에서 HTML 긁어오기  (1) 2013.01.15
Java Application 중복 실행 방지  (0) 2012.09.25
콘솔 출력 코드 추적  (0) 2012.08.29
솔라리스에서 64bit JDK설치  (0) 2012.05.31
이클립스 사용시 유용한 팁과 단축키  (0) 2012.05.31
Posted by 미랭군
데이터베이스2012. 9. 3. 11:40

네이버나 구글에서 DBCP 를 검색 해 보면 대부분 commons DBCP 를 많이 사용한다. 나도 그랬다. 내가 보고 있는 교재에서는 commons DBCP 로 설명하고 있다. 그러나 검색을 해보니 tomcat 에서 개발한 tomcat DBCP 가 있는데 이 것은 보다 향상된 connection pool 기능을 제공한다. 그래서 이번 포스트는 이에 대해서 설명을 해보고자 한다.

 

지난번 포스트 JNDI 를 수정하는 것이기 때문에 지난번 포스트인 JNDI 를 이용한 DBCP 를 먼저 읽어보길 바란다.

 

먼저 Tomcat DBCP Connection Pool 이 commons DBCP 보다 좋은 점이 뭔지에 살펴보자.

이 내용은 아파치 홈페이지에 있는 내용 중 몇 가지만 추린 내용이다.

http://people.apache.org/~fhanik/tomcat/jdbc-pool.html

 

- 새로운 dbcp 를 써야하는 이유

: commons dbcp 는 싱글 쓰레드를 사용한다. 그래서 스레드가 안전할 수 있도록 commons dbcp 는 전체 풀(pool) 에 대해서 롹(lock)을 건다.

: commons dbcp 는 느리다. 요즘 하드에워는 cpu 수가 증가하고 있는데 반해서 이를 제대로 활용하고 있지 못해서 퍼포먼스가 떨어진다.

: commons dbcp 는 복잡하다. 클래스 수가 60개나 된다. 반면, tomcat jdbc pool 은 딸랑 8개 이다. 이는 수정이 용의함을 의미한다.

: commons dbcp 는 정적인(static) 인터페이스(interface) 를 사용하기 때문에 구현 되지 않은 모든 메소드들에 대해서 예외(exception) 을 받게 될 수 있다.

: commons dbcp 는 상당히 업데이트 되지 않는다 ..

: tomcat jdbc pool 은 commons dbcp 에서 제공하지 않는 기능을 제공하면서도 빠르다.

: 추가적인 스레드를 더할 필요 없이 connection 을 비동기적(asynchronously) 회수할 수 있도록 구현할 수 있다.

 

- 추가된 기능

: 현재의 높은 멀티코어 환경을 충족시킨다.(혹은 제대로 활용한다??)

: inteface 의 동적인(dynamic) 구현(??)

: validation interval 을 설정해 줄 수 있다.

: 높은 퍼포먼스

: 간단해서 버그잡기가 용의. 핵심 클래스는 8개 뿐

 

- 단점

: 디비가 다운되었을 때, 재 연결을 위해서는 웹서버를 내렸다가 올려야 한다.(아무래도 미리 커넥션을 맺어둬서 그런 듯^^?)

 

 

'데이터베이스' 카테고리의 다른 글

MS SQL JDBC 등록 방법  (0) 2013.01.08
초 단위 출력  (0) 2012.11.20
Tomcat DBCP 설정법  (0) 2012.09.03
MyBatis 문자열 대체 방법  (0) 2012.08.24
Oracle UTF-8로 설정하기  (0) 2012.08.02
Posted by 미랭군
데이터베이스2012. 9. 3. 11:38

**DBCP**

DBCP (Database ConnectionPool) 

미리 컨넥션을 생성하여 컨넥션 풀에 저장한 다음

개별 클라이언트의 요청시 컨넥션을 빌려주고 

반납받는 형식으로 성능을 향상시키기 위한 프로그래밍 기법 

 

***********  Tomcat, Oracle Datasource 설정법  ********************

* 설정할때 이전에 설정된 tomcat 을 지우고 설정 후 server tab 에서 

새로 생성 하여야 한다.


1.conf/server.xml파일을 열고 <GlobalNamingResources>엘리먼트 안에 다음 내용 추가.

 <Resource name="jdbc/myoracle" auth="Container"

              type="javax.sql.DataSource" 

              driverClassName="oracle.jdbc.OracleDriver"

              url="jdbc:oracle:thin:@localhost:1521:xe"

              username="scott" password="tiger" 

               maxActive="20"

/>


2. conf/context.xml에 추가


  <ResourceLink global="jdbc/myoracle" name="jdbc/myoracle" type="javax.sql.DataSource"/>


3. 위와 같이 설정이 완료되었으면 이 파일을 실행하여 결과가 출력되는지 확인한다.

<%!

  private DataSource ds;

  public void jspInit(){

   try{

   InitialContext initCtx = new InitialContext();

   ds=(DataSource)initCtx.lookup("java:comp/env/jdbc/myoracle");

   System.out.println("dbcp lookup..");

   }catch(Exception e){

     e.printStackTrace();

   }

  }

%>


참고) JNDI(Java Naming and Directory Interface)는 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견(discover)하고 참고(lookup)하기 위한 자바 API다. (위키백과)

'데이터베이스' 카테고리의 다른 글

초 단위 출력  (0) 2012.11.20
Tomcat DBCP를 사용해야 하는 이유  (0) 2012.09.03
MyBatis 문자열 대체 방법  (0) 2012.08.24
Oracle UTF-8로 설정하기  (0) 2012.08.02
SQL Developer 실행시 오류  (0) 2012.08.01
Posted by 미랭군
스프링2012. 8. 31. 17:27

BeanFactory = ApplicationContext = IoC Container = Spring Container 가 생성/관리하는 빈 오브젝트는 


특별한 설정이 없는 한,  (빈의 scope이  prototype scope, request scope, session scope 이 아닌 이상..)


싱글톤 오브젝트이다.

이러한 이유로 Spring Container을 Sigleton Registry 라고도 부른다.


한 가지 기억해둘 것은 ..


빈으로 등록되는 클래스가 디자인 패턴의 하나인 Singleton pattern을 적용한 클래스가 아니다라는 점


빈으로 등록되는 클래스는 (private 생성자, public static getInstance() 메소드등이 없는) 평범한 클래스이다. 


이 평범한 클래스를 빈 컨테이너가 관리하면.. Singleton object가 된다


또 한 가지 더 기억해둘 것은 ..


빈으로 등록할 클래스는 Singleton Object가 되기 때문에.. 


stateless 방식으로 만들어야 된 다는 점, 


이유는 멀티쓰레드 환경에서 하나의 Object를 공유할 때 발생할 문제들을 애초에 없애기 위함이다.

Posted by 미랭군
자바·JSP2012. 8. 29. 10:10

System.out.println()는 매우 강력하고 사랑받는 디버깅 도구이다. 문제는, 이 코드를 디버그할 때는 잘 사용하고, 그 후에는 지우지 않는다는 점이다.

이런 일이 몇번 정도 반복되면, 불필요한 메시지가 콘솔에 무더기로 출력되어 꼭 필요한 디버깅 메시징을 보기가 힘들어지는 불상사가 벌어질 수 있다. 그러나 메시지를 어디서 출력하였는지 추적하는 것은 매우 힘들다. 시스템 콘솔 출력은 디버그를 이용하여 추적하는 것도 불가능하다. 방대한 양의 소스코드를 일일히 검색하는 것도 쉬운 일은 아니며, 또 메시지는 동적으로 생성된 것이어서 검색이 불가능 할 수도 있다.

이런 경우, 아래와 같은 간단한 디버깅 툴을 삽입해 이 문제를 해결 할 수 있다:

/**
 * @author Jeeeyul 2011. 11. 1. 오후 4:36:51
 * @since M1.10
 */
public class DebugStream extends PrintStream {
	private static final DebugStream INSTANCE = new DebugStream();
 
	public static void activate() {
		System.setOut(INSTANCE);
	}
 
	private DebugStream() {
		super(System.out);
	}
 
	@Override
	public void println(Object x) {
		showLocation();
		super.println(x);
	}
 
	@Override
	public void println(String x) {
		showLocation();
		super.println(x);
	}
 
	private void showLocation() {
		StackTraceElement element = Thread.currentThread().getStackTrace()[3];
		super.print(MessageFormat.format("({0}:{1, number,#}) : ", element.getFileName(), element.getLineNumber()));
	}
}

위와 같은 클래스를 하나 만든 뒤, DebugStream.activate()를 적절한 시점에 호출 해 주면 된다. 이 후로 System.out.println 을 통해 출력되는 메시지는 다음과 같이 보이게 된다:

(SemanticPatchSystem.java:47) : 세만틱 패치 수정 시작
(AbstractDiagramEditor.java:1140) : 메시지

이 형태로 인쇄한 경우, 콘솔에서 곧바로 클릭하여 해당 소스코드를 볼 수 있게 된다.

Posted by 미랭군
데이터베이스2012. 8. 24. 16:19

문자열 대체(String Substitution)

#{} 문법은 MyBatis 로 하여금 PreparedStatement 프로퍼티를 만들어서 PreparedStatement 파라미터(예를 들면, ?)에 값을 셋팅하도록 할 것이다. 이 방법이 안전하기는 하지만, 좀더 빠른 방법이 선호되기도 한다. 가끔은 SQL 구문에 변하지 않는 값으로 삽입하길 원하기도 한다. 예를 들면, ORDER BY 와 같은 구문들이다.

ORDER BY ${columnName}

여기서 MyBatis 는 문자열을 변경하거나 이스케이프 처리하지 않는다.

 중요 : 사용자로부터 받은 값을 이 방법으로 변경하지 않고 구문에 전달하는 건 안전하지 않다. 이건 잠재적으로 SQL 주입 공격에 노출된다. 그러므로 사용자 입력값에 대해서는 이 방법을 사용하면 안된다. 사용자 입력값에 대해서는 언제나 자체적으로 이스케이프 처리하고 체크해야 한다.

'데이터베이스' 카테고리의 다른 글

Tomcat DBCP를 사용해야 하는 이유  (0) 2012.09.03
Tomcat DBCP 설정법  (0) 2012.09.03
Oracle UTF-8로 설정하기  (0) 2012.08.02
SQL Developer 실행시 오류  (0) 2012.08.01
두 날짜 사이 날짜 구하기  (0) 2012.05.24
Posted by 미랭군
스프링2012. 8. 10. 11:45

<서론>

스프링 @MVC에서 ContentsNagotiator에서 JacksonJsonView로 자동으로 JSON으로 결과물을 생성되게 만들었습니다.
그과정에서 한가지 이슈가 있었습니다.
무엇이냐면 JSON을 리턴할때 무조건 객체가 2depth 이상으로 생성이 된다는 것입니다.

만약 컨트롤러에 아래와 같은 코드가 있다면,

   1: ModelAndView mav = new ModelAndView();
   2: mav.addObject(listOfObjects);
   3: return mav;

아래와 같은 JSON이 생성이 됩니다.


   1: {"objectList" : [{"name":"object1"}, {"name":"object2"}]}

그러나 제가 원하는 JSON은 아래와 같습니다.


   1: [{"name":"object1"}, {"name":"object2"}]


 

<본론>
해결 방안은 기본 JacksonJsonView를 상속하여 filterModel함수를 오버라이딩 하는 것입니다.


   1: import java.util.Map;
   2: import org.springframework.web.servlet.view.json.MappingJacksonJsonView;
   3:  
   4: public class MappingJacksonJsonViewEx extends MappingJacksonJsonView
   5: {
   6:     @SuppressWarnings("unchecked")
   7:     @Override
   8:     protected Object filterModel(Map<String, Object> model) {
   9:  
  10:         Object result = super.filterModel(model);
  11:         if (!(result instanceof Map)) {
  12:             return result;
  13:         }
  14:         Map map = (Map) result;
  15:         if (map.size() == 1) {
  16:             return map.values().toArray()[0];
  17:         }
  18:         return map;
  19:     }
  20: }

ApplicationContext에 설정하는 내용은 (완전한 내용을 포함하진 않았지만) 아래와 같이 됩니다.


   1: <-- default view-->
   2: <property name="defaultViews">
   3:     <list>
   4:         <ref bean="xmlView" />
   5:         <ref bean="jsonView" />
   6:     </list>
   7: </property>
   8:  
   9: <!-- JSON marshalling view -->
  10: <bean id="jsonView" class="ks.spring.sample.MappingJacksonJsonViewExtension" >
  11:     <property name="renderedAttributes" value="restRoot" />
  12: </bean>


 

<결론>

JSON을 한 depth 밖으로 빼내기 위해서, JacksonJSON Viewer의 기본 Filter를 변경시키는 것입니다.

'스프링' 카테고리의 다른 글

SecurityConfig  (0) 2022.05.25
Spring Boot Sample  (0) 2021.03.07
Singleton Registry = ApplicationContext의 또 다른 이름  (0) 2012.08.31
Spring Security - username 정보 가져오기  (0) 2012.01.09
Role in Spring security  (0) 2011.05.18
Posted by 미랭군

 

 

 

Capture Phase[EventPhase.CAPTURING_PHASE=1] : 이벤트가 발생하는 실제 오브젝트를 잡는 단계입니다.
Target Phase[EventPhase.AT_TARGET=2] : 실제 오브젝트를 잡은 단계입니다.
Bubbling Phase[EventPhase.BUBBLING_PHASE=3] : target부터 위로 이벤트가 발생합니다.

 

쉽게 생각하려면 마우스 포인터가 실제로는 스테이지 뒤에 있다고 생각하시면 됩니다.

옛날에 가운데에 유리를 놓고 양쪽에 자석 두개로 이리저리 움직이는 장난 많이 하셨죠? 나만 했었나 ㅋㅋ

그걸 상상해보시면 됩니다.

 

실제 마우스 포인터는 스테이지 뒤에 있고 화면에는 Child1 Node 앞에 마우스 포인터가 표시되는 것입니다. 이해가시나요?

Posted by 미랭군
리눅스2012. 8. 9. 14:27

touch 명령어란?

파일의 시간정보를 변경하는 명령어이지만, 크기가 0인 파일을 생성하는 용도로 자주 사용된다.

사용방법

touch [옵션] 파일이름

옵션

-a : 최근 파일 사용 시간만 변경한다.
-c : 파일이 존재하고 있지 않다면, 파일을 생성하지 않는다.
-d 시간 : 현재 시간대신 지정한 시간을 사용한다.
-m : 최근 파일변경 시간만 바꾼다.
-r 파일 : 현재시간 대신 지정한 파일의 시간으로 변경한다.

-t MMDDhhmm[[CC]YY][.ss] : 현재시간대신 지정한 시간으로 변경한다

Posted by 미랭군

톰캣은 catalina.<날짜>와 catalina.out 두개의 파일을 로깅하고 있어 퍼포먼스에 조금 신경이 쓰이는 부분이 있습니다.

톰캣의 conf 디렉토리 안에있는 logging.properties 안의 내용을 다음과 같이 수정하여 봅시다.

handlers = 1catalina.org.apache.juli.FileHandler

1catalina.org.apache.juli.FileHandler.level = INFO
1catalina.org.apache.juli.FileHandler.directory = ${catalina.base}/logs
1catalina.org.apache.juli.FileHandler.prefix = catalina.


위의 내용을 제외한 나머지는 모두 주석처리 해버리면 catalina.<날짜> 형태의 로그 외에는 모두 기록하지 않습니다.

개발환경이 아닌 단순 서비스 환경에서는 이렇게 로그를 최소화 하는것이 좋겠네요.

1catalina.org.apache.juli.FileHandler.level 의 값을 조정하여 로그 레벨을 정의할수도 있습니다.

 

기존 log생성 막기

먼저 catalina.out이 생성되는 것을 막기 위해

#  touch "$CATALINA_OUT"

처럼 주석처리를 해주고, 생성된 catalina.out에 로그를 찍는 것을 막기 위해

#      org.apache.catalina.startup.Bootstrap "$@" start \
#      >> "$CATALINA_OUT" 2>&1 &

위와 같이 if, else에 각각 하나씩 존재하는 부분을 둘 다 주석처리해줘야한다.


cronolog사용

http://cronolog.org 설치하여 세팅

설치하고자 하는 디렉토리로 이동

# cd /home/esb

cronolog tar파일 다운

# wget http://cronolog.org/download/cronolog-1.6.2.tar.gz

압축해제

# tar xzvf cronolog-1.6.2.tar.gz

해제된 디렉토리로 이동

# cd cronolog-1.6.2

환경에 맞게 설치

# ./configure --prefix=/home/esb/cronolog

# make && make install

# ls -al /home/esb/cronolog/sbin

$CATALINA_BASE/bin/catalina.sh를 편집한다.

org.apache.catalina.startup.Bootstrap "$@" start \
>> "$CATALINA_BASE"/logs/catalina.out 2>&1 &

org.apache.catalina.startup.Bootstrap "$@" \
start |/home/esb/cronolog/sbin/cronolog "$CATALINA_BASE"/logs/%Y-%m-%d.catalina.out >> /dev/null 2>&1 &

 

Posted by 미랭군