Spring, DI, AOP 적용

infoqoch·2021년 3월 12일
0

스프링

목록 보기
1/5

들어가며

  • 스프링에서 제공하는 DI와 AOP를 적용하는 과정을 정리하고자 한다.
  • DI란 하나의 객체를 만들기 위한 클래스 간 결합 스프링의 기법 중 하나이며, xml을 통한 외부 설정 방식과, 어너테이션을 통한 내부 설정 방식이 있다. 이번 논의는 자바를 통한 방식과 xml을 통한 방식 두 가지로 정리하겠다.

JAVA를 통한 DI 적용

클래스

Cook.java
public class Cook {
	private String food;
	
	public Cook(String food) {
		this.food = food;
	}

	
	public String getFood() {
		return food;
	}

	public void cooking() {
		System.out.println(food+"를 요리합니다.");
	}
}
Eat.java
public class Eat {
	private Cook cook;
		
	public Eat() {

	}

	public Eat(Cook cook) {
		super();
		this.cook = cook;
	}

	public void eatting() {
		System.out.println(cook.getFood()+"를 맛있게 먹습니다.");
	}

}
Shower.java
public class Shower {
	public void takingShower() {
		System.out.println("샤워를 합니다.");
	}

}
public class Watch {
	private String tvShow;

	public void setTvShow(String tvShow) {
		this.tvShow = tvShow;
	}
	
	public void watching() {
		System.out.println(tvShow+"를 시청합니다.");
	}
}

메인 스레드

public class Home {
	public static void main(String[] args) {
		
		Cook cook = new Cook("부대찌개");
		Eat eat = new Eat(cook);
		Shower shower = new Shower();
		Watch watch = new Watch();
		watch.setTvShow("뮤직뱅크");
		
		System.out.println("-----집에 도착했다.-------");
		cook.cooking();
		eat.eatting();
		shower.takingShower();
		watch.watching();
	}
}
  • 메인스레드는 cooking -> eatting -> takingShower->watching 을 순서로 작동한다. 이를 aop라고 핵심 기능이 takingShower이다. takingShower 매서드를 통해 나머지를 자동으로 사용할 수 없을까? 이러한 과정을 외부 xml을 통해 할 수 있을까?
  • xml을 통해 Bean의 선언과 초기화, 스레드의 작동 순서를 문서를 통해 통제한다. 이는 아래와 같다.

XML 설정

xml 설정 di, aop 설정

applicationContext.xml

<bean id="cook2" class="com.spring.test.Cook" c:food="짜장면"/>
<bean id="eat2" class="com.spring.test.Eat" c:cook-ref="cook2"/>
<bean id="shower2" class="com.spring.test.Shower"/>
<bean id="watch2" class="com.spring.test.Watch" p:tvShow="놀면뭐하니"/>

<aop:config>
	<aop:aspect ref="cook2" order="2">
		<aop:before method="cooking"
					pointcut="execution(* com.spring.test.Shower.*())"/>		
	</aop:aspect>
</aop:config>
<aop:config>
	<aop:aspect ref="eat2" order="1">
		<aop:before method="eatting"
					pointcut="execution(* com.spring.test.Shower.*())"/>
	</aop:aspect>	
</aop:config>

<aop:config>
	<aop:aspect ref="watch2">
		<aop:after method="watching"
					pointcut="execution(* com.spring.test.Shower.*())"/>
	</aop:aspect>
</aop:config>
  • bean 태그 : 빈 태그를 통해 객체를 생성한다. 생성한 객체는 두 가지 방식으로 데이타를 주입할 수 있다. 1) 생성자의 매개변수(c:food="짜장면", c:cook-ref="cook2") 2) 매소드의 매개변수(p:tvShow="놀면뭐하니")
  • aop 태그 : pointcut : 핵심 기능이 무엇인지를 작성한다. execution()에 해당 내용을 삽입한다. 리턴 타입, 접근제어자, 클래스, 매서드 등 원하는 핵심 기능을 세세하게 작성할 수 있다. 여기서는 Shower 클래스가 어떤 매서드(*)를 사용하든 AOP를 작동한다는 의미이다.
  • aop 태그 : after/before : 핵심기능이 작동하기 이전과 이후 무엇을 할 것인지 작성한다. order를 통해 순서를 설정한다.

메인 스레드

public class Home {
	public static void main(String[] args) {
		
        System.out.println("------AOP와 함께 집에 도착했다.--------");
		AbstractApplicationContext context = 
				new GenericXmlApplicationContext("classpath:applicationContext.xml");
		Shower shower2 = (Shower) context.getBean("shower2");
		shower2.takingShower();	
	}
}
  • ApplicationContext 인터페이스는 네 가지의 상속한 클래스가 있다. GenericXmlApplicationContext은 xml 파일을 통해 di와 aop를 설정한다.
  • getBean을 통해 컨텍스트로부터 이미 초기화가 된 빈을 가지고 온다. 해당 메서드(takingShower)가 실행 될 때, 전후 작업을 자동적으로 수행한다(AOP).

DI, AOP를 위한 몇 가지 설정

  • DI, AOP 명세서(xml)
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:c="http://www.springframework.org/schema/c"
xmlns:p="http://www.springframework.org/schema/p"
  • maven 의존성 설정 (pom.xml)
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjtools</artifactId>
	<version>1.7.4</version>
</dependency>
  • di의 초기화 때, NoArgsConstructor 를 통해 초기화한다. 빈에 매개변수가 있는 생성자가 있을 경우, 반드시 매개변수가 없는 생성자도 만들자.
profile
JAVA web developer

0개의 댓글