Spring/Spring

23-03-22 Spring

모건이삼촌 2023. 3. 22. 19:29

※ 복습

 

 

 

 

※ 수업

1. AOP (관점지향 프로그래밍 / 교재 446p)

 - 코드를 작성하면서 염두해두어야 할 일

   1) 파라미터가 올바르게 들어왔는지

   2) 이 작업을 하는 사용자가 적절한 권한을 가진 사용자인지(권한여부)

   3) 작업에서 발생할 수 있는 모든 예외는 어떻게 처리해야 하는가(흐름제어)

      - 예외처리는 조건처리와 비슷함. 어떤 예외가 발생했을때 이런 흐름으로 제어해야하는가

 - AOP가 추구하는 것은 관심사(concern)의 분리이다.

   - 개발자가 염두에 두어야 하는 일들은 별도의 관심사로 분리하고 핵심 비즈니스 로직만을 작성할것을 권장

 - 개발자가 작성한 코드와 분리된 관심사를 구현한 코드를 컴파일 혹은 실행시점에 결합시킴

 - 

 

*

java > jsp > spring

c      > php > code ignitor, laravel 잘 안씀

        > cgi 망함

VB   > asp

C#  >  asp.net > .net

python > django

               node.js 

 

 

*

객체

자바에서는 class로 해석함

절차형 프로그래밍에 덧붙인게 객체지향 프로그래밍이다.

 

 

 

2. AOP 용어들 (중요도 상당히 높음)

 - 구현이 목적이 아닌 구현을 서포트 하는 역할

 - 기존에 있는 AOP를 해석하여 사용할줄 알아야 한다.

 

 - 기존코드를 수정하지 않고, 원하는 기능들과 결합할 수 있는 패러다임

 

하나의 타겟은 여러 메서드를 가질 수 있음 (메서드의 후보군이 모두 joinpoint이다, / 메서드가 될수도, 패키지가 될수도, 클래스가 될 수 도 있다.)

pointcut은 조건식이다.

 

타겟은 aop가 걸'릴' 대상

프록시는 aop가 걸'린' 대상

advice는 추가로 할 일이라고 해석하자.

advice+pointcut = Aspect(advisor)

advisor = Aspect(Aspect가 하나만 있어도 Advisor가 될 수 있다)

위빙(weaving)은 에스펙트를 대상 객체에 적용하여 새로운 프록시 객체를 생성하는 과정을 말함

 

우선 타겟, 위빙 프록시까지만 우선적으로 외우자

원본 타겟

타겟이 걸린 결과물 프록시

타겟이 걸리는 과정을 위빙

 

예제) 스프링 기본적인 형태의 프록시 생섬

package aop.aop1;

public interface HelloWorld {
	void sayHello(String msg);
}

package aop.aop1;

// 이 클래스를 가지고 객체를 만들면 타겟이 됨
public class HelloworldImpl  implements HelloWorld{

	@Override
	public void sayHello(String msg) { //joinpoint
		System.out.println("안녕하세요 " + msg);
	}

}

package aop.aop1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class HelloWorldHandler implements InvocationHandler{
	private Object object;
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("전처리");
		Object o = method.invoke(object, args); // 실제 처리
		System.out.println("후처리");
		return o;
	}
	
}

package aop.aop1;

import java.lang.reflect.Proxy;

public class HelloMain {
	 public static void main(String[] args) {
		 
		 // helloWorld : target
		HelloWorld helloWorld = new HelloworldImpl();
		helloWorld.sayHello("반갑습니다 자바맨");
		
		System.out.println("======================");

		//proxy 생성
		HelloWorld proxy = (HelloWorld)Proxy.newProxyInstance(HelloWorld.class.getClassLoader(),
				new Class[] {HelloWorld.class}, new HelloWorldHandler(helloWorld));
		proxy.sayHello("반가워요 프록시");
	}
}

실행결과

안녕하세요 반갑습니다 자바맨
======================
전처리
안녕하세요 반가워요 프록시
후처리

 

프록시라고 하는 추가 객체가 생김, 컴파일러는 프록시와 타겟이 같은것인지 아닌지 판단을 못함

 

3. advice

 - 실제 걱정거리를 분리해놓은 코드를 의미, 동작위치에 따라 다음과 같이 구분이 됨

구분 설명
Before Advice Target의 JoinPoint를 호출하기 전에 실행되는 코드, 코드에 실행자체에는 관여할 수 없음
(자주 사용)
After Returnung Advice 모든 실행이 정상적으로 이루어진 후에 동작하는 코드
After Thowing Advice 예외가 발생한 뒤에 동작하는 코드
After Advice 정상적으로 실행되거나 예외가 발생했을 때 구분없이 실행되는 코드
Aroung Advice 메서드의 실행 자체를 제어할 수 있는 가장 강력한 코드, 직접 대상 메서드를 호출하고 결과나 예외를 처리할 수 있음

- 스프링 3버전 이후에는 어노테이션만으로도 모든 설정이 가능하다.

- target에는 어떤 어드바이스를 적용할 것인지는 xml을 이용한 설정을 이용할 수 있고, 어노테이션을 이용하는 방식을 이용할 수 있음

 

※ Spring AOP는 2가지의 방식이 있다.

1. java.lang.reflect의 Proxy를 이용하여 AOP를 이용하는 방식 (원본에 있는 인터페이스(ClassLoader)를 통한구현)

2. CGLIB를 이용해서 사용하는 방식(상속을 통한 구현)

 

상속을 통해서 추가 프록시를 생성

호출지점(전처리, 후처리)을 제어할 수 있음

 

상속받지 못하는경우

 - 상속받을 대상이 fanal 클래스일 경우

   - 인터페이스를 통한 우회접근 밖에 되지 않는다.

 

예제2)

package aop.aop2;

public class HelloWorld {
	public void sayHello(String msg) {
		System.out.println("안녕하세요 " + msg);
	}

}

package aop.aop2;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MsgDecorator implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("전처리");
		// invocation.proceed()는 invoke이다. 전 예제에 super.method와 같음, 하드코딩 방식보다 좀 더 심플함
		return invocation.proceed();
	}

}

package aop.aop2;

import org.springframework.aop.framework.ProxyFactory;

public class HelloWorldMain {
	public static void main(String[] args) {
		HelloWorld target = new HelloWorld();
		target.sayHello("target");
		
		// proxy 생성
		ProxyFactory pf = new ProxyFactory();
		
		// 어드바이스 추가
		pf.addAdvice(new MsgDecorator());
		
		// 위빙할 타겟을 정의
		pf.setTarget(target);
		
		// 프록시 생성
		HelloWorld proxy = (HelloWorld)pf.getProxy();
		
		// proxy의 sayHello 호출
		proxy.sayHello("proxy");
	}

}

HelloWorld 클래스를 final 클래스로 바꾸면 생기는 에러

 

※ Spring의 AOP지원

 1. 널리쓰이는 AOP 프레임워크

  - AspectJ

  - JBOXX AOP

  - Spring AOP

 

Spring과 AspectJ의 결합으로 시너지 가능

 

2. Spring AOP 지원

 - ProxyFactory 기반 AOP 프로그래밍적 접근

 - 선언적 AOP 설정 메커니즘

   - aop 네임스페이스

   - ProxyFactoryBean 클래스 기반

   - @ASpectJ 어노테이션 기반 Aspect

 

3. Spring의 AOP

 3-1 스프링의 advice는 자바로 작성

  - pointcut의 경우 advice를 어디에 적용할지를 정의하는 데 보통 XML설정 파일에서 한다

     * pointcut 표 삽입(p.449 하단)

구분 설명
execution(@execution) 메서드를 기준으로 pointcut을 설정함
within(@whthin) 특정한 타입(Bean, 클래스)를 기준으로 pointcut을 설정
this 주어진 인터페이스를 구현한 객체를 대상으로 pointcut을 설정함
args(@args) 특정한 파라미터를 가지는 대상들만을 pointcut으로 설정
@annotation 특정한 어노테이션이 적용된 대상들만을 pointcut으로 설정 (Target)

  - AspectJ는 자바언어를 확장한 형태로 구현, 새로운 도구와 문법을 배워야 한다.

 

3-2 스프링의 Aspect는 실행시간에 만들어진다.

  - 빈을 감싸는 프록시 객체를 실행시간에 생성하므로 Aspect가 Spring 관련 빈에 위빙된다. 프록시 객체는 타겟 객체로 위장해서 메소드 호출을 가로채고, 타겟 객체로 호출을 전달한다

  - 애플리케이션이 실제 프록시 객체를 필요로 할 때까지 타겟을 생성하지 않으므로 즉 프록시가 실시간으로 생성, 애스펙트를 위빙하기위해 별도 컴파일러가 ㅣㄹ요없다.

1번이 첫번째 예제

 

4. Spring의 AOP

 4-1 스프링의 애스팩트

 - 스프링 aop에서 애스펙트는 어드바이저 인터페이스를 구현한 클래스의 인터페이스로 펴시

 - 스프링은 이러한 어드바이저를 구현한 몇 개의 클래스를 제공

 - 

  - pointcutadvisor : 인터페이스

 

advice 예제)

 

※Pointcut

 - 조건형태 라고 생각하면 편함

 - AOP기반으로 애플리케이션을 개발하는 경우 포인트컷을 사용하는경우는 많지안흥ㅁ

 - Spring 프레임워크에서 지원하는 포인트컷은 메서드 이름을 기준으로 하고 있음

 - AOP기반으로 애플리케이션을 개발하다보면 패키지, 클래스별로 포인트컷을 적용해야하는경우도 종종 발생함

 - 스프링의 AOP의 한계점을 극복하기 위한 일환으로 다른 AOP툴과의 통합이 필요한 경우가 있는데 AspectJ가 가장 널리 사용된다.

 

1. pointcut 구현체

 - aspcetj.AspectJExpressionPointcut만 종종 사용

 

2. Advisor

 - pointcut, advice 두개의 메서드가 있음

 

 

※  AOP (Aspect(코드를 바라보는형태의 관점) Oriented Programming)

핵심로직 > 핵심관심사(core concern)  <분리> 공통로직 > 공통관심사(cross concern)

 

target : aop의 대상( who)

advice : aop의 해야할 일 (what)

joinpoint : target내의 method (when)

pointcut : joinpoint의 선별 (where)

aspect(advisor) : advice + pointcut

proxy : aop가 처리된 결과

weaving : aop의 처리과정

 

2. 구현방식

2-1. interface를 통한 proxy 방식

2-2. 상속을 통한 CGLIB방식

 

3. Spring에서 구현 방법

 - spring aop(aopalliance), aspectJ

 

4. 객체 생성 방법

proxy자체를 생성, ProxyFactory

ProxyFactoryBean, namespace aop : , annotation

 

금일 수업중에서는 구현에 대한 방식과 약간의 개념을 배움

'Spring > Spring' 카테고리의 다른 글

23-03-29 Spring  (0) 2023.03.30
23-03-23 Spring  (0) 2023.03.23
23-03-21 Spring 비밀글  (0) 2023.03.21
23-03-17 Spring  (0) 2023.03.17
23-03-16 Spring  (0) 2023.03.16