로그 찍는 거 별로 안좋아하는데 로그를 찍어보니까 더 좋은 것 같아요 ^^
게다가 log4j라는 매우 우수한 로그찍는 프로그램이 있습니다.
sysout에서 벗어나봅시다-_-; 습관적으로 sysout을-_-(System.out.println()......-_-)

우선 이클립스에서 프로젝트를 하나 만들어봅시다.
log4j를 받아봅시다.
http://logging.apache.org/log4j/1.2/download.html
1.2버전입니다. 받아서 log4j-1.2.15.jar파일을 라이브러리에 추가합시다.

log4j설정파일을 만들어봅시다.
최상위 폴더에다가 log4j.properties파일을 만듭시다.
[code]
# Log4j Setting file
log4j.rootLogger=INFO, console

# Daily file log
log4j.appender.logfile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File=D:/mudchobo/Log/glv.log
log4j.appender.logfile.DatePattern='.'yyyy-MM-dd
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=[%d{HH:mm:ss}][%-5p](%F:%L) - %m%n

# Console log
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-5p %l - %m%n

# log level and appender
log4j.logger.com.mudchobo=DEBUG, console
log4j.logger.com.mudchobo.Test=INFO, logfile
[/code]
대략 내용을 살펴보면 log4j.rootLogger는 최상위 로거입니다.
모든 INFO레벨이상의 로그는 다 console로 찍겠다는 겁니다.
(레벨에는 DEBUG, INFO, WARN, ERROR, FATAL 순인데, 예를 들어 INFO레벨로 지정해두면 logger.debug로 찍는 로그는 나타나지 않습니다. INFO레벨 이상것만 나타납니다.)

console은 아래 #Console log쪽에 보시면
log4j.appender.console <- 요 이름입니다.
요 console은 자세히보면 ConsoleAppender라는 클래스입니다. 이건 말그대로 콘솔에 로그를 찍어준다는 겁니다. layout에는 PatternLayout을 지정할 수 있는데 저 패턴은 뭐 레벨이 뭐고, 클래스가 뭐고, 메시지찍고 뭐 그런 내용입니다. 검색 고고싱-_-;

그리고, 파일에다가 출력 할 수 있는데, DailyRollingFileAppender클래스를 이용합니다. 이눔은 말그대로 매일매일 다른로그를 사용하게 만듭니다. 로그이름이 위와 같이 glv.log라면, 해당로그가 어제날짜인데 로그를 찍으려고 하면 기존에 있던 파일은 glv.log.2008-04-17 이렇게 바꿔줍니다.

아래부분에 보면 log4j.logger. 다음에 패키지명이나 클래스명을 지정해놓고, 로그레벨과 출력할 로그를 지정할 수 있는데요. 해당 클래스나 패키지의 로그는 저걸로 찍겠다는 겁니다. Test클래스는 logfile로 찍힌다는 겁니다.
그리고, rootLogger가 colsole로 지정되어 있기 때문에 console에도 찍히겠죠? ^^

로그를 찍어봅시다.
TestLogging이라는 프로젝트 이름으로 만듭시다.

Test클래스를 만들어봅시다.
Test.java
[code]
package com.mudchobo;

import org.apache.log4j.Logger;

public class Test {

 private Logger logger = Logger.getLogger(getClass());
 
 public void println() {
  logger.info("안녕하세요! Test입니다");
 }
}
[/code]
Test2클래스를 만들어봅시다.
Test2.java
[code]
package com.mudchobo;

import org.apache.log4j.Logger;

public class Test2 {

private Logger logger = Logger.getLogger(getClass());
 
 public void println() {
  logger.info("안녕하세요! Test2입니다.");
 }
}
[/code]
TestLogging클래스를 만들어봅시다. 메인을 만들어야합니다.
[code]
package com.mudchobo;

public class TestLogging {

 public static void main(String[] args) {
  Test test = new Test();
  Test2 test2 = new Test2();
 
  test.println();
  test2.println();
 }
}
[/code]
자 그럼 콘솔에는
INFO  com.mudchobo.Test.println(Test.java:10) - 안녕하세요! Test입니다.
INFO  com.mudchobo.Test.println(Test.java:10) - 안녕하세요! Test입니다.
INFO  com.mudchobo.Test2.println(Test2.java:10) - 안녕하세요! Test2입니다.
INFO  com.mudchobo.Test2.println(Test2.java:10) - 안녕하세요! Test2입니다.
이렇게 출력이 될 것이고 로그파일에는
[19:56:35][INFO ](Test.java:10) - 안녕하세요! Test입니다.
이것만 출력될 것입니다.
위에 콘솔에 두번 찍힌 이유는 Rootlogger도 찍고, 아래 패키지를 지정한 로그도 찍었기 때문이죠.
그리고, 파일에는 한번만 쓰여진 이유는 파일에 쓰는건
log4j.logger.com.mudchobo.Test=INFO, logfile 여기 이 Test클래스 하나죠-_-;
이상입니다-_-;


 
Posted by 머드초보
,
 

보통 어플리케이션에서 Properties를 사용하려면 Properties클래스를 사용해서...
Properties properties = new Properties();
properties.load(new FileInputStream("C:/~~~파일명경로");
String mudchobo = properties.getProperty("mudchobo");

이렇게 하면 풀경로를 다 적어줘야지 되더라구요.

이 파일이 클래스패스에 넣어두면 classpath:file.properties 하면 먹혔으면 좋겠는데 안먹히더라구요-_-;
그래서 스프링을 사용하면 클래스패스에 넣어도 할 수 있어요!(아놔 이렇게 하는거 맞나-_-)

properties패키지에 있는 file.properties파일을 불러올겁니다.
mudchobo=dwaeji
hermusseri=meongchungi
2개의 property가 있습니다.

우선 applicationContext.xml파일입니다.
[code]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 <bean id="messageSource"
  class="org.springframework.context.support.ResourceBundleMessageSource"
  p:basename="properties/file" />
 
 <bean id="messageSourceAccessor"
  class="org.springframework.context.support.MessageSourceAccessor">
  <constructor-arg ref="messageSource" />
 </bean>
</beans>
[/code]
잘 보면 messageSource라는 bean이 있는데 이것은 ResourceBundleMessageSource구요.
p:basename은 해당패키지에서 파일을 찾더라구요.
properties라는 패키지에 file.properties파일을 지정했습니다.

그다음 bean은 MessageSourceAccessor인데요. 말그대로 메시지소스를 접근하는 접근자라고 자신을 표현하고 있네요. 이것의 생성자로 해당 messageSource를 받는군요.

애플리케이션에서 봅시다.
[code]
package test;

import java.util.Locale;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.MessageSourceAccessor;

public class Test {
 
 public static void main(String[] args) {
  String[] configLocation = {"applicationContext.xml"};
  ApplicationContext context = new ClassPathXmlApplicationContext(configLocation);
 
  MessageSourceAccessor msAccessor =
   (MessageSourceAccessor)context.getBean("messageSourceAccessor");
 
  System.out.println(context.getMessage("mudchobo", null, Locale.getDefault()));
  System.out.println(context.getMessage("hermusseri", null, Locale.getDefault()));
  System.out.println(msAccessor.getMessage("mudchobo"));
  System.out.println(msAccessor.getMessage("hermusseri"));
 }
}
[/code]
MessageSourceAccessor를 선언해서 해당 bean을 가져옵니다.
그러면 MessageSourceAccessor를 통해서 Message를 가져올 수 있습니다.
저걸 사용하지 않게 된다면 ApplicationContext인터페이스에서 getMessage를 지원해서 저걸 통해서도 가져올 수 있습니다. 저렇게 가져온다면, 여기저기 다른 클래스에서 사용하게 된다면 context를 해당 클래스로 넘겨야하는데 이건 applicationContext에서 MessageSourceAccessor를 DI해버리면 해당 클래스에서 사용할 수 있겠죠?^^

다시 말하지만... 정말 이것말곤 방법이 없나-_-; 그냥 Properties에서 할 수 있을 것 같은데-_-;

 
Posted by 머드초보
,
 

사용자 삽입 이미지

저는 자바 코딩할 때 성능에 관해서는 전혀 모르고 있었는데-_-; 이것참 배워야 할 것이 많고, 고쳐야할 습관이 많다는 것을 깨닫게 해주네요. ^^ 우리들이 코딩하면서 무심코 그냥 쓰는 습관들이 성능면에서 얼마나 약영향을 끼치는지 잘 알게 해줍니다 ^^

책에 주인공은 나초보씨입니다. 신입으로 막 입사한 초보씨가 프로젝트에 투입되면서 자바에 대해서 알아가고, 성능의 차이를 점점 배워가면서 성장하는(프로그래머메이커인가-_-;) 가슴찡한 휴먼....아.....-_-; 아니다. 어쨌든 그런 소설같은게 아니라 자바성능을 조금이나마 향상 시키고, 위험한 코드를 작성하고 있다는 것을 조금이마나 알려주는 좋은 튜닝관련 책입니다. 절대.....소설이 아닙니다-_-;

최근 프로파일링이 뜨던데 이게 뭔가 했더니 성능을 측정하는 것이였군요. 한번도 사용해본 적이 없는데 한 번 해봐야겠군요. 무료 툴로는 넷빈즈에 있다고 하더군요. 넷빈즈를 사용하면서도 몰랐네요^^
비슷한 역할을 하는 것들에 대해 성능테스트도 저자가 열심히 삽질한 거 보니 삽질의 대가이신 것은 분명합니다-_-; 다들 귀찮아서 그냥 넘어갔을 부분까지도 꼭 집어서 성능의 차이를 느끼게 만드네요 ^^

자바 기본을 배운지 오래된 사람들에게 좋은 책이 될 듯 싶습니다. 저는 기본을 군대가기전에 배웠는데 다시 보니 새롭게 안 사실들도 많았고 꽤나 도움이 되었습니다. 자바 개발자들에게 추천해주고 싶네요 ^^

 
Posted by 머드초보
,
 

이제 Manager클래스를 만들어봅시다.
실제로 BlazeDS를 이용해서 가져오는 놈은 이 Manager클래스가 되겠죠^^

Java Resources: src에서 오른쪽버튼 클릭하고, New를 해서 interface를 구현합니다.
[code]
package springapp.service;

import java.util.List;
import springapp.domain.Product;

public interface ProductManager {
 public List<Product> getProducts();
}
[/code]
getProducts라는 메소드가 하나 있군요! 구현해봅시다!!!
[code]
package springapp.service;

import java.util.List;

import springapp.dao.ProductDao;
import springapp.domain.Product;

public class ProductManagerImpl implements ProductManager {

 private ProductDao productDao;
 
 @Override
 public List<Product> getProducts() {
  return productDao.getProductList();
 }

 public void setProductDao(ProductDao productDao) {
  this.productDao = productDao;
 }
}
[/code]
getProducts라는 함수는 Dao에서 getProductList를 호출하는 놈이네요.
요 아래에는 setter가 있네요. 이건 spring에서 DI를 하기위해 존재하는 setter입니다^^
서비스도 완성이 되었네요! 이제 설정파일을 작성해봅시다.

applicationContext.xml
[code]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <!-- Enable @Transactional support -->
 <tx:annotation-driven />

 <!-- Enable @AspectJ support -->
 <aop:aspectj-autoproxy />

 <aop:config>
  <aop:advisor pointcut="execution(* *..ProductManager.*(..))"
   advice-ref="txAdvice" />
 </aop:config>

 <tx:advice id="txAdvice">
  <tx:attributes>
   <tx:method name="save*" />
   <tx:method name="get*" read-only="true" />
  </tx:attributes>
 </tx:advice>

 <bean id="productManager"
  class="springapp.service.ProductManagerImpl">
  <property name="productDao" ref="productDao" />
 </bean>

</beans>
[/code]
Dao부분의 설정파일인 applicationContext-ibatis.xml파일을 봅시다.
applicationContext-ibatis.xml
[code]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <bean id="propertyConfigurer"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  p:location="classpath:properties/jdbc.properties" />

 <bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"
  p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
  p:username="${jdbc.username}" p:password="${jdbc.password}" />

 <!-- Transaction manager for iBATIS Daos -->
 <bean id="transactionManager"
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <property name="dataSource" ref="dataSource" />
 </bean>

 <!-- SqlMap setup for iBATIS Database Layer -->
 <bean id="sqlMapClient"
  class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
  <property name="dataSource" ref="dataSource" />
  <property name="configLocation"
   value="classpath:springapp/dao/SqlMapConfig.xml" />
 </bean>

 <!-- Add additional Dao definitions here -->
 <bean id="productDao"
  class="springapp.dao.ProductDaoImpl">
  <property name="sqlMapClient" ref="sqlMapClient" />
 </bean>
 
</beans>
[/code]
jdbc.properties파일은 properties라는 package를 만들고, jdbc.properties파일을 넣어버립시다.
[code]
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://DB주소
jdbc.username=DB아이디
jdbc.password=DB비밀번호
[/code]
이 설정들의 bean들의 관계를 보고 싶다면-_-;
Spring Elements에서 오른쪽버튼 클릭하고 properties를 선택.
Bean Support를 선택, Add한 뒤 두개의 설정파일(applicationContext.xml, applicationContext-ibatis.xml)선택.
Config set에서 New하고 Name에 applicationContext라고 하고, 두개다 체크 오케이~
그럼 이제 스프링 설정파일에서 에러를 찾아낼 수 있어요!
bean들의 관계를 그래프로도 볼 수 있네요!
Config set에 추가한 applicationContext에다가 마우스오른쪽버튼을 클릭하면 open graph로 볼 수 있어요!

이제 클라이언트 구현으로....다음 시간에-_-;

 
Posted by 머드초보
,
 
초간단시리즈-_-;
스프링에 있는 bean을 플렉스에서 가져다가 쓸 수 있어요!
멋져요!-_-;

우선 준비물! 저의 테스트 환경입니다.
Eclipse IDE for Java EE Developers  : http://www.eclipse.org/downloads/
Flex Builder 3 Eclipse Plug-in(로그인후받을 수 있음) :
http://www.adobe.com/cfusion/tdrc/index.cfm?product=flex_eclipse
JDK 6 update 5 : http://java.sun.com/javase/downloads/index.jsp
Apache Tomcat 6.0.16 : http://tomcat.apache.org/download-60.cgi
Spring Framework 2.5.2 : http://www.springframework.org/download
BlazeDS : http://opensource.adobe.com/wiki/display/blazeds/Downloads
Spring과 BlazeDS연동라이브러리 : blazeds-spring-beta1.jar 현재 beta1이군요.
http://www.igenko.org/archiva/repository/igenko/com/adobe/flex/blazeds-spring/
JDK6을 먼저 설치를 합니다.
이클립스는 받아서 그냥 압축을 풀어버립시다.
그리고, 플렉스빌더3 이클립스 플러그인을 설치 합니다.
톰캣은 ZIP버전이면 그냥 압축을 풀어놓고 JAVA_HOME을 잡아줍시다-_-;
스프링프레임워크는 lib파일을 가져다 쓸것이니 아무대나 압축을 풀어놓읍시다.

셋팅이 완료가 되었으면 이클립스를 띄웁시다.
File -> New -> Project선택, Flex Project선택 후 Next
Project이름은 SpringAndBlazeds라고 지어봅시다-_-;
Application Type은 Web Application이라고 하고, Application server type은 J2EE로 선택합니다.
넥스트를 하고 Target runtime에서 Tomcat을 설정해야합니다.
New한다음에 Apache폴더에 Tomcat 6.0을 선택하고, 해당 톰캣의 경로를 지정합니다.
Finish를 클릭하고, flex WAR파일을 선택하라고 하는데 받아놓은 blazeds.war파일을 선택하면 됩니다.
Finish를 클릭하면 끝납니다-_-; 셋팅이 완료가 되었어요!

이제 스프링IDE를 설치해봅시다.
이클립스메뉴에서 Help -> Software Updates -> Find And Install 선택
Search for new features to install를 선택 후 Next
New Remote Site선택 Name은 Spring IDE, url은 http://springide.org/updatesite/ 라고 씁니다.
추가한 것만 체크된 상태에서 Finish클릭!
Search Result에서 Spring IDE선택.
그러면 몇개는 설치 못하는데 설치 못하는 것은 체크해제를 시켜요-_-;
Dependencies에서 Spring IDE Dependencies 체크해제
Integration에서 Spring IDE AJDT Intergration 체크해제
AspectJ Development Tools도 설치하려면 하세요(전 사용할 줄 몰라요^^)
Next -> agree -> finish하면 설치가 됩니다.
설치가 다 되면 이클립스ide를 restart하라고 나와서 리스타트하면 돼요^^

그리고 우리가 만든 프로젝트에  마우스 오른쪽버튼을 클릭해서
Spring Tools -> Add Spring Project Nature선택 하면 완료됩니다.

필요한 라이브러리를 복사해봅시다.
dist/spring.jar : 스프링프레임워크를 쓰기 위해 꼭 필요한 놈.
dist/module/spring-test.jar : 스프링테스트 할 때 필요한 놈.
lib/jakarta-commons/commons-logging.jar : 로그찍을 때 필요한 놈.
lib/ibatis/ibatis-2.3.0.677.jar : ibatis쓸 때 필요한 놈.
lib/cglib/cglib-nodep-2.1_3.jar : Junit으로 테스트 할 때 필요한데, JUnit테스트를 할 때에는 Interface가 구현이 안되어있어서(aop를 사용하려면 interface가 구현이 되어있어야 한다고 하더군요) 필요한 놈.
lib/aspectj/aspectjweaver.jar : aop때문에 필요한 놈 같은데-_-;
lib/junit/junit-4.4.jar : JUnit을 사용하기 위해 필요한 놈.
mysql-connector-java-5.1.5-bin.jar : mysql Connector. db가 다른거면 다른 Connector가 있으면 돼요!
blazeds-spring-beta1.jar : 위에서 설명한 spring과 blazeDS와 연동할 때 필요한 놈.

셋팅은 여기까지-_-;
 
Posted by 머드초보
,