[필기정리] Day110-1 - AOP 예제문제

Web/Spring

2020. 11. 27. 11:53

Q1. 다음의 요소를 가지는 Student 클래스를 만든다.

private String name; 
private int age; 
private int gradeNum; 
private int classNum;


위에 멤버변수에 대한 각각의 getter, setter을 만든다.
이름, 나이, 학년, 반을 출력하는 getStudentInfo 메소드를 만든다.

다음의 요소를 가지는 Worker 클래스를 만든다.

private String name; 
private int age; 
private String job;


위에 멤버변수에 대한 각각의 getter, setter을 만든다.
이름, 나이, 직업을 출력하는 getWorkerInfo 메소드를 만든다.

LogAop클래스를 만든다.
loggerAop메소드를 만들고 메소드가 시작할때 메소드의 시그니처를 출력한다.
그리고 시작한 시간을 저장한다.
끝나는 시간을 저장한다.
그리고 메소드의 시그니처를 출력한다
그리고 시작시간과 끝시간의 경과시간을 출력한다.

Spring bean Configuration 파일에서 Student와 Work 빈을 생성한다.
student는 세터 인젝션으로 이름 홍길동, 나이 10, 학년 3, 번호 5로 초기화 한다.

worker는 세터 인젝션으로 이름 홍길순, 나이 35, 직업 개발자로 초기화 한다.

그리고 annotation을 이용하여 

위에 Student, Worker 클래스가 속한 모든 메소드에 around 속성으로 loggerAop 메소드가 실행되게 한다.

 

A.

- Student.java

package com.tistory.coderbear;

public class Student {

	private String name;
	private int age;
	private int gradeNum;
	private int classNum;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public int getGradeNum() {
		return gradeNum;
	}
	public void setGradeNum(int gradeNum) {
		this.gradeNum = gradeNum;
	}
	public int getClassNum() {
		return classNum;
	}
	public void setClassNum(int classNum) {
		this.classNum = classNum;
	}
	
	public void getStudentInfo() {
		System.out.println("이름 : " + getName());
		System.out.println("나이 : " + getAge());
		System.out.println("학년 : " + getGradeNum());
		System.out.println("반 : " + getClassNum());
	}
}

- Worker.java

package com.tistory.coderbear;

public class Worker {

	private String name;
	private int age;
	private String job;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public void getWorkerInfo() {
		System.out.println("이름 : " + getName());
		System.out.println("나이 : " + getAge());
		System.out.println("직업 : " + getJob());
	}
}

- LogAop.java

package com.tistory.coderbear;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LogAop {
	
	@Pointcut("within(com.tistory.coderbear.*)")
	private void pointcutMethod() {
	}
	
	
	@Around("pointcutMethod()") // 포인트컷을 통해 메소드 이름 작성하여 참조
	public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable {
		String signatureStr = joinpoint.getSignature().toShortString();
		System.out.println( signatureStr + " is start.");
		long st = System.currentTimeMillis();
		
		try {
			Object obj = joinpoint.proceed(); // student.getStudentInfo()와 worker.getWorkerInfo()가 여기서 실행됨
			return obj;
		} finally {
			long et = System.currentTimeMillis();
			System.out.println( signatureStr + " is finished.");
			System.out.println( signatureStr + " 경과시간 : " + (et - st));
		}
		
	}
	
	@Before("within(com.tistory.coderbear.*)") // 메소드 실행 전에 beforAdvice()가 실행되는 것
	public void beforAdvice() {
		System.out.println("beforAdvice()");
	}
}

- MainClass.java

package com.tistory.coderbear;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

	public static void main(String[] args) {
		
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX.xml");
		Student student = ctx.getBean("student", Student.class); 
		student.getStudentInfo();
		
		Worker worker = ctx.getBean("worker", Worker.class);
		worker.getWorkerInfo();
		
		ctx.close();
	}
}

- log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
		</layout>
	</appender>
	
	<!-- Application Loggers -->
	<logger name="com.tistory.coderbear">
		<level value="info" />
	</logger>
	
	<!-- 3rdparty Loggers -->
	<logger name="org.springframework.core">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.beans">
		<level value="info" />
	</logger>
	
	<logger name="org.springframework.context">
		<level value="info" />
	</logger>

	<logger name="org.springframework.web">
		<level value="info" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="warn" />
		<appender-ref ref="console" />
	</root>
	
</log4j:configuration>

- applicationCTX.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

	<aop:aspectj-autoproxy />
	<bean id="logAop" class="com.tistory.coderbear.LogAop" />

	<bean id="student" class="com.tistory.coderbear.Student" >
		<property name="name" value="홍길동" />
		<property name="age" value="10" />
		<property name="gradeNum" value="3" />
		<property name="classNum" value="5" />
	</bean>
	
	<bean id="worker" class="com.tistory.coderbear.Worker" >
		<property name="name" value="홍길순" />
		<property name="age" value="35" />
		<property name="job" value="개발자" />
	</bean>
	
</beans>

// 최근 xml보다 annotation을 더 선호하는 추세이다.

 

+ ex)

- LogAop.java

package com.tistory.coderbear;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LogAop {
	
//	@Pointcut("execution(public void get*(..))")	// public void인 모든 get메소드
//	@Pointcut("execution(* com.javalec.ex.*.*())")	// com.javalec.ex 패키지에 파라미터가 없는 모든 메소드
//	@Pointcut("execution(* com.javalec.ex..*.*())")	// com.javalec.ex 패키지 & com.javalec.ex 하위 패키지에 파라미터가 없는 모든 메소드
//	@Pointcut("execution(* com.javalec.ex.Worker.*())")	// com.javalec.ex.Worker 안의 모든 메소드

//	@Pointcut("within(com.javalec.ex.*)")	//com.javalec.ex 패키지 안에 있는 모든 메소드
//	@Pointcut("within(com.javalec.ex..*)")  //com.javalec.ex 패키지 및 하위 패키지 안에 있는 모든 메소드
//	@Pointcut("within(com.javalec.ex.Worker)") //com.javalec.ex.Worker 모든 메소드
	
//	@Pointcut("bean(student)")	//student 빈에만 적용
	@Pointcut("bean(*ker)")		//~ker로 끝나는 빈에만 적용
	private void pointcutMethod() {
	}
	
	
	@Around("pointcutMethod()") 
	public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable {
		String signatureStr = joinpoint.getSignature().toShortString();
		System.out.println( signatureStr + " is start.");
		long st = System.currentTimeMillis();
		
		try {
			Object obj = joinpoint.proceed();
			return obj;
		} finally {
			long et = System.currentTimeMillis();
			System.out.println( signatureStr + " is finished.");
			System.out.println( signatureStr + " 경과시간 : " + (et - st));
		}
		
	}
	
	@Before("pointcutMethod()")
	public void beforAdvice() {
		System.out.println("beforAdvice()");
	}
	
}

// AspectJ 문법 : * - 모든, . - 현재, .. - 0개 이상을 뜻함

728x90