- this.getClass().getResource();

- this.getClassLoader().getResource();

- Thread.currentThread().getContextClassLoader().getResource();

- MyClass.class.getResource();

위 4가지의 차이점은 아래 링크 참조.

http://www.javaworld.com/javaworld/javaqa/2002-11/02-qa-1122-resources.html
http://www.jroller.com/coreteam/entry/loading_configuration_files_under_web


그럼 스프링 사용환경에서는 보통 어떻게 로딩하지?

일단 링크 걸어두고 읽어봐야겠다.

http://static.springframework.org/spring/docs/2.5.x/reference/resources.html
http://www.carbonfive.com/community/archives/2007/05/using_classpath.html


Posted by 에코지오
,

아래 글의 트랜잭션 처리와 관련하여 내가 겪었던 상황을 살펴볼까한다.

- 삽질했던 상황 -

DB로부터 목록을 조회한 후 목록안의 개별 아이템에 대한 작업을 수행한 뒤
개별 아이템별로 작업결과를 DB에 반영한다.

로직은 별로 복잡하지 않다. 근데 문제는 이거 2가지다.

- 전체 작업이 아니라 개별 작업결과를 커밋하길 원한다.
- 개별 작업은 1~10초 정도 시간이 걸리는 네트워크 작업이다.

처음에 아래처럼 코드를 작성했다.

public void 전체작업() {
  전체 목록 조회;
  for (아이템 : 전체목록) {
      try {
          아이템작업(아이템);
      } catch(에러) {
         //로깅
      }
  }
}

public void 아이템작업(아이템) throws 네트워크에러, DB에러 {
    네트워크작업(아이템);
    작업결과처리(아이템);
}

@Transactional
private void 작업결과처리(아이템) {
     // 아이템 가공
     dao.save(아이템);
}

나름 트랜잭션 스코프도 최소화하고 독립적으로 개별 아이템작업을 처리하기 위해 신경썼는데,

무지막지하게 삽질을 해댔으니... RTFM이 떠오른다.

이제 위 코드에서 왜 트랜잭션이 작동하지 않는지 이유를 알았으니 해결방안을 찾아야겠다.

Posted by 에코지오
,
http://static.springframework.org/spring/docs/2.0.x/reference/transaction.html#transaction-declarative

위 사이트의 9.5.6. Using @Transactional 부분.

첫째, @Transactional은 인터페이스(및 메소드), 구현클래스(및 public 메소드)에 붙일 수 있다.
특히나 public 메소드에만 적용되는 점은 아래와 같이 설명하고 있다.
Method visibility and @Transactional

When using proxies, the @Transactional annotation should only be applied to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error will be raised, but the annotated method will not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

둘째, self-invocation 상황(내부 호출)에서는 적용되지 않는다. 즉 외부의 클래스에서 그 메소드를
호출해야 트랜잭션이 걸린다.

Note: Since this mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted. This means that 'self-invocation', i.e. a method within the target object calling some other method of the target object, won't lead to an actual transaction at runtime even if the invoked method is marked with @Transactional!

며칠 동안 두가지 상황을 모두 겪으면서 삽집한 생각을 하면... 으 ...... 바보같다.. ㅠ.ㅠ

궁금점 : @Transactional을 Class 선언부에 안붙이고 메소드에만 붙이면 어떻게 되는거지?
여기저기 찾아보면 당최 메소드에만 붙어있는 예제가 없다.


Posted by 에코지오
,
AppFuse-light 버전이 너무 간단한거 같아 AppFuse 2.x를 받아서
소스 좀 볼 요량으로 appfuse.org를 갔는데 웬걸 다운로드 링크가 없다... ㅠㅠ

설치 자체가 Maven을 이용하는 것으로 바뀌었다. 헐... 메이븐 설치도 안했는뎅!~

우선 Spring-MVC Basic 아키타입을 받고,

mvn archetype:create -DarchetypeGroupId=org.appfuse.archetypes -DarchetypeArtifactId=appfuse-basic-spring -DremoteRepositories=http://static.appfuse.org/releases -DarchetypeVersion=2.0.1 -DgroupId=com.mycompany.app -DartifactId=myproject

myproject 디렉토리로 이동해서 mvn 날린후 아래 명령으로 전체 소스를 받는다.

mvn appfuse:full-source
혹시 받다가 URL 관련 에러날 경우에는 apache-maven-2.0.8\conf\settings.xml 를 열고,
로컬 메이븐 저장소 경로를 디폴트 경로(C:\Documents and Settings\Administrator\.m2\repository)에서
스페이스 없는 경로로 바꾸면 된다.

<settings>
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ~/.m2/repository
  -->
  <localRepository>D:\MavenRepository</localRepository>

* 자바지기님의 메이븐 강좌도 참고하자.
Maven 강좌 7 - Maven을 이용하여 Appfuse 프로젝트 생성하기

Posted by 에코지오
,
Spring+Hibernate 조합 환경에서 단위테스트에 대한 토비님의 글.

AppFuse DAO Test 코드의 문제점

Rod Johnson의 Testing with Spring

Spring기반의 Hibernate DAO Unit Test 만들기

특히나 하이버네이트의 1차레벨 캐쉬 때문에

C/U/D 한 뒤 다시 객체를 읽어오는 경우 읽기전에 세션을 flush 해주어야 한다는 지적은

AppFuse 만든 Matt도 미처 몰랐던 사실!


spring-test 모듈의 AbstractTransactionalJUnit4SpringContextTests 사용환경에서는 아래처럼
만들어 놓고 중간중간 flushAndClearSession(); 해주면 될 듯. 
 @Autowired
 protected SessionFactory sessionFactory;

 protected Session getCurrentSession() {
  return SessionFactoryUtils.getSession(sessionFactory, true);
 }

 protected void flushSession() {
  getCurrentSession().flush();
 }

 protected void flushAndClearSession() {
  Session s = getCurrentSession();
  s.flush();
  s.clear();
 }



Posted by 에코지오
,
이클립스에서 static import 설정 팁.
http://whiteship.tistory.com/1416

스프링 2.5 레퍼런스의 테스트 부분.
http://static.springframework.org/spring/docs/2.5.x/reference/testing.html

스프링 샘플에 포함된 petclinic 테스트 소스 참고.
http://www.springframework.org/docs/petclinic.html

최범균님 스프링2.5 프로그래밍 책의 테스트 파트.


그 외.
http://mudchobo.tomeii.com/tt/233

http://otamot.tistory.com/61

http://cafe.naver.com/deve/2580
Posted by 에코지오
,