본문 바로가기

스프링

[spring] aop_다이내믹프록시_리플렉션_2

1.     Com.springsource.javax.activation : Spring java-mail

2.     Com.springsource.javax.mail : Spring java-mail

3.     Com.springsource.junit : junit

4.     Commons-logging : Spring-context가 사용

5.     Mail : java-mail

6.     Mockito : 목 프레임워크 중 Mockito

7.     Mysql-connector : Mysql JDBC

8.     Org.springframework.context.support : Spring java-mail

9.     Spring-aop : 스프링 기능 자체의 aop

10.   Spring-bean : 스프링 빈을 활용하는 경우 필요. 스프링의 XML 설정파일과 자바 애노테이션을 파싱 하는데 필요한 클래스 포함

11.   Spring-context : 스프링 코어를 확장한 많은 클래스가 들어 있는데 모든 클래스는 EJB, JNDI(Java Naming Directory Interface), JMX용 클래스와 연동하는데 applicationcontext기능을 사용해야 하며 스프링 리모팅 클래스, 동적 스크립팅 언어(제이루비, 그루비등)와 연동하는 클래스, 빈 유효성검증(JSR-303) API, 스케줄링을 하는 클래스도 포함되어 있다.

12.   Spring-core : 모든 스프링 모듈에서 필요한 모듈. 다른 스프링 모듈에서 사용하는 공통 클래스가 포함됨.

13.   Spring-dao : EmpltyResultDataAccessException 등 사용을 위한 jar

14.   Spring-expression : 스프링 표현언어(SpEL) 지원 클래스 포함.

15.   Spring-jdbc : 스프링이 지원하는 jdbc.

16.   Spring-test.jar

-       @RunWith : Junit 프레임워크의 테스트 실행방법을 확장시 사용.

-       SpringJUnit4ClassRunner : 어플리케이션컨텍스트를 만들고 관리하는 확장 클래스

-       @ContextConfiguration(경로) : 자동으로 만들어줄 어플리케이션 컨텍스트 설정파일

17.   Spring-tx : DuplicateKeyException.class 파일 존재 및 스프링 트랜잭션

 

 

프록시 : UserServiceTx처럼 클라이언트의 요청을 자기가 타깃인척 하는 오브젝트

1. 다이내믹 프록시 : 프록시 팩토리에 의해 런타임시 다이내믹하게 만들어지는 오브젝트

 

 

트랜잭션 경계설정을 분리하 듯이 대문자로 변환하는 로직도 인터페이스로 프록시와 타깃을 따로 구현하여 유지보수를 용이하게 할 수 있다.

 

 

비즈니스 로직 타깃 클래스

 

 

클라이언트가 이 로직을 사용하는 것처럼 느낄 수 있는 프록시 클래스

단점 : toUpperCase가 중복되고, 인터페이스를 모두 구현해야된다(구지 안해도 되는 것도)

 

 

6. InvocationHandler : 프록시로서 부가기능이 필요한 부가기능 코드 작성시 구현, 다이내믹 프록시로부터 요청을 전달 받으려면 구현해야함.

12. InvaocationHandler 구현시 구현해야할 메소드는 invoke 한 개다.

> Method : 리플렉션의 Method 인터페이스를 파라미터로 받는다.

> Object[] args : 메소드 호출할 때 전달되는 파라미터도 args로 받는다.

> 클라이언트 요청 > 다이내믹 프록시 오브젝트(Proxy.newProxyInstance)는 클라이언트의 모든 요청을 리플렉션 정보로 변환해서 invoke 메소드로 넘긴다.

13. Method.invoke() 사용시 대상 메소드 실행.

> String : Hello 인터페이스의 모든 메소드의 결과가 String 이므로 변환해도 안전함.

14. 다이내믹 프록시의 장점 : 이거 하나로 모두 통일 가능하다. 매번 인터페이스 구현을 위한 코드를 구현할 필요가 없다.

 

* 단점

> 모든 메소드의 리턴타입이 스트링이라고 가정함. (14)

> 13라인 어차피 리플렉션의 Method 인터페이스를 이용해 타깃의 메소드를 호출하는 것이니 Hello 타입의 타깃으로 제한할 필요가 없다.

> 밑에 다이내믹 프록시 확장편 참조

 

22. Proxy.newProxyInstance : 다이내믹 프록시 생성

> newProxyInstance : 스태틱 팩토리 메소드

23. getClass.getClassLoader() : 런타임에 클래스 파일을 찾고 로딩하는 임무

24. new Class : 다이내믹 프록시가 구현해야할 인터페이스

 

프록시 팩토리에게 다이내믹 프록시를 요청하면 Hello 인터페이스의 모든 메소드를 구현한 오브젝트를 생성해 준다. InvocationHandler 인터페이스를 구현한 오브젝트를 제공해주면 다이내믹 프록시가 받는 모든 요청을 InvocationHandlerinvoke 메소드로 처리한다.

 

 

타겟에 부가기능(트랜잭션 경계설정)을 프록시로 구현하기 위한 인터페이스. 타겟 클래스는 수정하지 않겠다는 의지.

 

 

타겟 (비즈니스 로직)

 

 

프록시. 하지만 위처럼 소스가 중복되고 프록시가 필요없는 부분까지 인터페이스인 관계로 모두 구현해야 한다는 단점이 있음. 그래서 이렇게 안쓰고 다이내믹 프록시가 필요하다.

3개가 아니라 30개의 메소드라면??? 어마어마한 중복이 발생하고 구현해야한다.

 

 

8.     어떤 인터페이스를 구현한 타깃에서도 적용가능하도록 커스터마이징

18.   String 타입과 메소드 이름으로 구분 가능