관리 메뉴

민우의 코딩노트

자바 AOP 예제 정리 - 순수 자바로 AOP 구현해보기 본문

Knowledge/Spring

자바 AOP 예제 정리 - 순수 자바로 AOP 구현해보기

미미누 2022. 3. 22. 12:40

https://www.youtube.com/watch?v=pr2dwdf_03k 

public class NewlecExam implements Exam {

	@Override	
	public int total() {
    	int result = a1+a2+a3+a4;
    	return result;
    }
    
    @Override	
    public float avg() {
    	 float result = total() / 4.0f;
         return result;
    }


}

Exam.class를 상속받은 newlecExam.class

 

public class Program {
	
    public static void main(string[] args) {
    	Exam exam = new NewlecExam(1,1,1,1);
        
        System.out.printf("total is %d\n", exam.total());
    }

}

Exam이 갖고 있는 총점을 출력하는 Program.class

업무를 다루는 사용자의 관점에서 요구하는 총점을 출력하는 코드

하지만 다른 관점(개발자, 관리자)가 필요로 하는 세부코드가 필요할 때는 어떻게 해야할까?

ex) 시작과 끝부분에 얼마나 시간이 걸리는지 확인

 

public class NewlecExam implements Exam {

	@Override	
	public int total() {
    	
        long start = System.curretTimeMillis();
        
    	int result = a1+a2+a3+a4;
        Thread.sleep(200);
        
        long end = System.curretTimeMillis();
        
        String message = (end-start) + "ms";
        System.out.println(message);
    	return result;
    }
    
    @Override	
    public float avg() {
    	 float result = total() / 4.0f;
         return result;
    }


}

관점이 다른 사람에 의해서 만들어짐. 즉 시간을 재는 코드(곁다리 업무)를 추가했음.

사용자의 수준에서 원하는 코드는 단순히 합을 구하는 코드임을 알 수 있음.

but 이거는 옛날 방식.

 

곁다리 업무를 분리하기 위해서 어떻게 해야할까?

곁다리 업무를 원래 업무 로직과 연결시키 위해서 프록시를 이용하면 된다.

 

public class Program {
	
    public static void main(string[] args) {
    	Exam exam = new NewlecExam(1,1,1,1);
        
        Exam proxy = (Exam)Proxy.newProxyInstance(newlecExam.class,
        			new Class[] {Exam.class},
                    new InvocationHandler() {
                    
                    	@Override
                        public Object invoke(Object proxy, Method method, Object[] args) {
                        	long start = System.curretTimeMillis();
        
        					// method는 실제 업무를 실행할 수 있는 메서드 호출 가능
                            // invoke를 사용하여 실제 업무 객체를 넣어준다 (exam)
                            // 두 번째 인자 args : exam안에 여러 메서드를 넣을 수 있음.
                            // invoke는 Object 형으로, 모든 형태를 반환 가능
                            Object result = method.invoke(exam, args);
        					long end = System.curretTimeMillis();
        
        					String message = (end-start) + "ms";
        					System.out.println(message);
                            
                            return result;
                        
                        
                        }
        			
        
        System.out.printf("total is %d\n", proxy.total());
        System.out.printf("total is %d\n", proxy.avg());
    }

}

Exam이란 가짜 exam(프록시)를 만들려고 한다.

프록시를 이용하면, 곁다리 업무를 포함한 exam을 호출한다.

 

Proxy.newProxyInstance(loader, interfaces, h)

 

loader 부분은 실제 객체를 로드하는 부분.

interfaces 부분은 복수형 이기 때문에 Exam.class 배열로 제공

h 부분은 곁다리 업무를 꽂는 부분 즉 시간을 재는 코드를 넣으면 된다!

invocationHandler를 구현한 클래스를 만들어야 한다. but 익명 클래스를 직접 작성하면 된다.

invoke 안에 위 아래는 넣고 싶은 부분(곁다리 업무), 중간 부분에는 실제 업무를 호출하는 부분을 구현하면 된다.

 

실행하면 총합을 구하는 부분, 평균을 구하는 부분의 시간 값을 구할 수 있다!