보름
492
2021-04-16 20:42:17 작성 2021-04-16 20:43:31 수정됨
4
198

AOP공부를 시작했습니다. 하지만 의문이 있어요.


AOP라는게 결국 실제 작업을 시작하기 전과 후에 원하는 작업을 추가하는 것 같은데요.

아래는 방금 제가 공부한 것입니다.


원본코드입니다.


public class MainClass {

	public static void main(String[] args) {

		ApplicationContext context = new AnnotationConfigApplicationContext(DISettings.class);
		ExmServiceList exmServiceList = context.getBean(ExmServiceListImpl.class);
		
		try {
			exmServiceList.print();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.print(e.getMessage());
		}
		
		((AnnotationConfigApplicationContext) context).close();
		
	}
	
}



위 코드에 AOP 를 적용한 것이 아래 코드입니다.

	public static void main(String[] args) {

		ApplicationContext context = new AnnotationConfigApplicationContext(DISettings.class);
		final ExmServiceList exmServiceList = context.getBean(ExmServiceListImpl.class);
		
		ExmServiceList proxy = (ExmServiceList) Proxy.newProxyInstance(
				ExmServiceListImpl.class.getClassLoader(), 
				ExmServiceListImpl.class.getInterfaces(), 
				new InvocationHandler() {
					
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						Long start = System.currentTimeMillis();
						Object result = method.invoke(exmServiceList, args);
						Long end = System.currentTimeMillis();
						System.out.println("소요시간 : " + (end - start) + "ms");
						return result;
					}
				});
		try {
			proxy.print();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.print(e.getMessage());
		}

		((AnnotationConfigApplicationContext) context).close();
		
	}


이제 막 AOP라는것을 공부하기 시작했습니다.


궁금한 것은  아래 처럼 하면 쉬운걸 굳이 왜 Proxy라는것을 이용하는 수고를 하느냐는 것입니다.

public class MainClass {

	public static void main(String[] args) {

		ApplicationContext context = new AnnotationConfigApplicationContext(DISettings.class);
		ExmServiceList exmServiceList = context.getBean(ExmServiceListImpl.class);
				
                Long start = System.currentTimeMillis();

		try {
			exmServiceList.print();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.print(e.getMessage());
		}
		
                Long end = System.currentTimeMillis();
		System.out.println("소요시간 : " + (end - start) + "ms");

		((AnnotationConfigApplicationContext) context).close();
		
	}
	
}



아직 공부가 부족해 깊은 뜻을 알지 못하니 가르쳐 주시면 공부 열심히 하겠습니다.

0
  • 답변 4

  • Dierslair
    4k
    2021-04-16 20:52:23

    관심사의 분리가 핵심입니다. 예제에는 간단한 수행시간 로깅이라 코드가 비교적 짧지만 트랜잭션 관리, 캐시 처리 등 복잡한 로직이 비즈니스 로직 전/후에 필요한 경우에는 작성하는 모든 비즈니스 로직의 전/후에 해당 코드를 넣는 것이 매우 부담이 됩니다. 만약 정책이 변경되어 전/후에 실행되는 코드를 수정해야 한다면? 전/후에 실행하는 코드가 100개, 1000개의 메서드에 반복되어 작성된 거라면? 생각만 해도 정신이 아찔해집니다. AOP는 핵심 로직의 전/후에 공통적으로 작성되어야  하는 코드를 깔끔하게 분리하기 위한 수단입니다. jdbc 커넥션 관리, 트랜잭션 관리 정도만 배우시면 AOP/프록시의 고마움을 느끼게 됩니다.

  • 보름
    492
    2021-04-16 20:56:39

    제가 이제 막 시작한 공부이다 보니 말씀하신 내용이 상상이 안되는데요/

    전후에 해야 하는 작업이 많아지면 제가 올려드린 마지막 코드와 같은 방식으로 하는 대신 

    시작 시간과 끝나는 시간을 구하는 부분을 각각 별도의 클래스로 만들어 분리한 후에

    그 클래스를 호춣해도 되는거 아닌가요?

    공부를 하다 보면 알게될지 몰라도 지금으로써는 보이는것이 제 수준에서라....

  • 라이칸
    589
    2021-04-16 21:20:05

    예를 들어서  controller 단에 로그인을 체크해서  service 를 넘어가야하는 상황이있어요

    그럼 각각에 controller 안에 로그인 user 를 체크하는  소스를 각각에 다 추가하잖아요?

    프로그램이 하나면 모르겠지만 100개 200개 늘어날수록 매번 user 체크 기능을 넣어줘야하는데

    aop 경우엔 그것들은 간단하게 한 파일에서 관리를 할수있다는 장점이 있죠...저도 계속 공부하고있거든요..

    ----

    위와같이 저코드를 계속 붙이다가 만약 저코드에 무언가를 수정할상황이 발생된다면 100건에 추가했던것들을 바꿔야겠죠? 그래서 aop를 하면 한번에 쉽게 바꿀수있는 장점도 있죠 


  • 장독깨기
    2k
    2021-04-16 22:14:21

    네.. 클래스 만들어두고 각 함수에서 호출하면 됩니다.

    근데 그거 까지도 하지 않겠다는거죠. 그게 AOP 목적입니다.

    그리고, Spring 이 AOP 를 지원하니 우리가 직접 AOP 를 구현하는게 아니고,..

    (즉, 글쓴님 처럼 직접 Proxy를 써서 구현하는게 아니구요..)

    우리가 만든 함수 호출 전후로 뭔가 공통적인 할 일(실행타임측정)이 있다면,

    스프링이 지원하는 AOP 규칙(어노테이션)에 따라 적용하면 됩니다.

    근데 뭐 쓸 일이 거의 없긴 합니다. 전 AOP 적용해본적이 없어요..ㅋ


  • 로그인을 하시면 답변을 등록할 수 있습니다.