국비학원 61일차(Spring-ENV, AOP)

써니·2022년 10월 19일
0

spring

목록 보기
3/23

🌞Spring

🔻och05_env

🌍환경작업

[env03 - annotation]


  • AdminConnection.java
    interface - initializingBean / disposableBean
    afterPropertiesSet() -> 환경작업(생성자와 같은 역할)
package env03;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class AdminConnection implements InitializingBean, DisposableBean {
	private String adminId;
	private String adminPw;
	private String sub_adminId;
	private String sub_adminPw;
	
	public void destroy() throws Exception {
		System.out.println("AdminConnection destory() 소멸자가 소멸되기 전...");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("AdminConnection afterPropertiesSet() 생성자 생성이후");
	}
	
	public String getAdminId() {
		return adminId;
	}
	public void setAdminId(String adminId) {
		this.adminId = adminId;
	}
	public String getAdminPw() {
		return adminPw;
	}
	public void setAdminPw(String adminPw) {
		this.adminPw = adminPw;
	}
	public String getSub_adminId() {
		return sub_adminId;
	}
	public void setSub_adminId(String sub_adminId) {
		this.sub_adminId = sub_adminId;
	}
	public String getSub_adminPw() {
		return sub_adminPw;
	}
	public void setSub_adminPw(String sub_adminPw) {
		this.sub_adminPw = sub_adminPw;
	}
}

  • ApplicationConfig.java

@Configuration --> @로 환경 설정

package env03;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

@Configuration
public class ApplicationConfig {
	
	@Value("${admin.id}")
	private String adminId;
	@Value("${admin.pw}")
	private String adminPw;
	@Value("${sub_admin.id}")
	private String sub_adminId;
	@Value("${sub_admin.pw}")
	private String sub_adminPw;
	
	@Bean
	public static PropertySourcesPlaceholderConfigurer Properties() {
		PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
		System.out.println("2. Properties Run...");
		Resource[] locations = new Resource[2];
		locations[0] = new ClassPathResource("admin3.properties");
		locations[1] = new ClassPathResource("sub_admin3.properties");
		configurer.setLocations(locations);
		return configurer;
	}
	
	@Bean
	public AdminConnection adminConfig() {
		AdminConnection adminConnection = new AdminConnection();
		System.out.println("3. adminConfig Run");
		adminConnection.setAdminId(adminId);
		adminConnection.setAdminPw(adminPw);
		adminConnection.setSub_adminId(sub_adminId);
		adminConnection.setSub_adminPw(sub_adminPw);
		return adminConnection;
	}
}

  • EnvMainClass03.java
package env03;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class EnvMainClass03 {

	public static void main(String[] args) {
		System.out.println("1 EnvMainClass03 Run...");
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		System.out.println("4 EnvMainClass03 adminConfig Before Run");
		AdminConnection connection = ctx.getBean("adminConfig", AdminConnection.class);
		System.out.println("5 EnvMainClass03 adminConfig After Run");
		
		System.out.println("connection.getAdminId() adminId : "+connection.getAdminId());
		System.out.println("connection.getAdminPw() adminPw : "+connection.getAdminPw());
		System.out.println("connection.getSub_adminId() sub_adminId : "+connection.getSub_adminId());
		System.out.println("connection.getSub_adminPw() sub_adminPw : "+connection.getSub_adminPw());
		ctx.close();
	}

}

  • admin3.properties( File )
admin.id=super
admin.pw=12345

  • sub_admin3.properties( File )
sub_admin.id=sub3
sub_admin.pw=67890




🔎xml / anntation 비교
위-xml / 아래-annotation




[env04 - server]

  • ServerInfo.java
package env04;

public class ServerInfo {
	private String ipNum;
	private String portNum;
	
	public String getIpNum() {
		return ipNum;
	}
	public void setIpNum(String ipNum) {
		this.ipNum = ipNum;
	}
	public String getPortNum() {
		return portNum;
	}
	public void setPortNum(String portNum) {
		this.portNum = portNum;
	}
}

  • EnvMainClass04.java
    ctx.getEnvironment().setActiveProfiles(config); -> profile 세팅
package env04;

import java.util.Scanner;

import org.springframework.context.support.GenericXmlApplicationContext;

public class EnvMainClass04 {

	public static void main(String[] args) {
		String config = null;
		System.out.println("System을 입력하세요? dev OR run");
		Scanner scanner = new Scanner(System.in);
		String str = scanner.next();
		if(str.equals("dev")) {
			config = "dev";
		} else if(str.equals("run")) {
			config = "run";
		}
		scanner.close();
		
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
		ctx.getEnvironment().setActiveProfiles(config);
		ctx.load("applicationCTX_dev.xml", "applicationCTX_run.xml");
		
		ctx.refresh();
		
		ServerInfo info = ctx.getBean("serverInfo", ServerInfo.class);
		System.out.println("ip : "+ info.getIpNum());
		System.out.println("port : "+ info.getPortNum());
		ctx.close();
	}
}

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

	<bean id="serverInfo" class="env04.ServerInfo">
		<property name="ipNum" value="localhost"/>
		<property name="portNum" value="8181"/>
	</bean>
</beans>

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

	<bean id="serverInfo" class="env04.ServerInfo">
		<property name="ipNum" value="172.30.1.21"/>
		<property name="portNum" value="8080"></property>
	</bean>
</beans>

dev

run





💡 AOP

AOP(Aspect Oriented Programming)

  1. 관점 지향 프로그램의 정의
  • 핵심 관심사(Core Concerns)에 대한 관점과 횡단 관심사(Cross-cutting Concerns)에 대한 관점들로 프로그램을 분해해 객체지향 방식(OOP)에서 추구하는 모듈을 효과적으로 지원하도록 하는 프로그래밍 기법

  1. AOP
    joinpoint - 핵심관심사가 들어가는 지점

  1. ❗ Spring AOP Advice 종류
    Around를 많이 씀





🔻och06_AOP1

porm.xml -> aspectjweaver - aop

[aop1 - Student]

핵심 관심사 - Student, Worker

  • Student.java
package aop1;

public class Student {
	private String name;
	private int age;
	private int gradeNum;
	private int classNum;
	
	public void getStudentinfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("학년 : "+getGradeNum());
		System.out.println("반    : "+getClassNum());
	}
	
	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;
	}
}

  • Worker.java
package aop1;

public class Worker {
	private String name;
	private int age;
	private String job;
	
	public void getWorkerInfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("직업 : "+getJob());
	}
	
	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;
	}
}

  • LogAop.java
    퍼포먼스 측정
    Advice
package aop1;

import org.aspectj.lang.ProceedingJoinPoint;

public class LogAop {
	// Around Advice에서 사용할 공통기능 메서드는,대부분 파라미터로 전달받은 ProceedingJoinPoint의 proceed() 메서드만 호출
	// ProceedingJoinPoint의 proceed() 메서드만 호출 
	public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable {
		// 핵심관심사 Method
		String signatureStr = joinpoint.getSignature().toShortString();
		System.out.println(signatureStr + " is start...");
		// Returns the current time in milliseconds
		long startTime = System.currentTimeMillis();
		
		Object obj;
		try {
			// 핵심관심사 Method 수행
			obj = joinpoint.proceed();
			return obj;
		} finally {
			long endTime = System.currentTimeMillis();
			System.out.println(signatureStr + " is finished.");
			System.out.println(signatureStr + " 경과시간 : " + (endTime - startTime));
		}
	}
}

  • AopMainClass01.java
package aop1;

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

public class AopMainClass01 {

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

  • applicationCTX01.xml( aop + bean )
  • logAop - aspect 지정
  • weaving - 엮어줌
  • pointcut expression="within(aop1.*)" -> Event 지정 (aop1내에 모든 것)
  • around - 시작과 끝을 지정해주는 것
<?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">

	<bean id="logAop" class="aop1.LogAop"></bean>
	
	<aop:config>
		<aop:aspect id="logger1" ref="logAop">
			<aop:pointcut expression="within(aop1.*)" id="pointcut1"/>
			<aop:around method="loggerAop" pointcut-ref="pointcut1"/>
		</aop:aspect>
	</aop:config>
	
	<bean id="student" class="aop1.Student">
		<property name="name" value="연개소문"/>
		<property name="age" value="50"/>
		<property name="gradeNum" value="3"/>
		<property name="classNum" value="5"/>
	</bean>
	
	<bean id="worker" class="aop1.Worker">
		<property name="name" value="이순신"/>
		<property name="age" value="35"/>
		<property name="job" value="개발자"/>
	</bean>
</beans>




🔎 expression="within(aop1.S*)" 변경하면?

Student에 관련된 것만 나오고 worker는 자기가 알아서 찾아감


🔎 expression="within(aop1.*)" 다시되돌리면?




🔻och06_AOP2

[aop2.buz - 패키지 분리]

  • Student.java -> 일부로 오류냄

핵심 관심사 - Student, Worker

package aop2.buz;

public class Student {
	private String name;
	private int age;
	private int gradeNum;
	private int classNum;
	
	public Student() {
		System.out.println("Student 생성자");
	}
	
	public void getStudentinfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("학년 : "+getGradeNum());
		System.out.println("반    : "+getClassNum());
		// 어쩌다 오류
		// System.out.println(10/0);
	}

	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;
	}
}

  • Worker.java
package aop2.buz;

public class Worker {
	private String name;
	private int age;
	private String job;
	
	public void getWorkerInfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("직업 : "+getJob());
	}

	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;
	}
}

[aop2]

  • LogAop.java
package aop2;

import org.aspectj.lang.ProceedingJoinPoint;

public class LogAop {
	public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable {
		// 핵심업무에 사용 method
		String signatureStr = joinpoint.getSignature().toString();
		long st = System.currentTimeMillis();
		System.out.println(signatureStr + " is start...");
		
		try {
			// 핵심업무 수행 aop2.buz.Student.getStudentInfo()
			Object obj = joinpoint.proceed();
			return obj;
		} finally {
			long et = System.currentTimeMillis();
			System.out.println( signatureStr + "is finished.");
			System.out.println( signatureStr + "경과시간 : "+(et - st));
		}
	}
	
	public void beforeAdvice() {
		System.out.println("beforeAdvice()");
	}
	
	public void afterReturningAdvice() {
		System.out.println("afterReturningAdvice()");
	}
	
	public void afterThrowingAdvice() {
		System.out.println("afterThrowingAdvice()");
	}
	
	public void afterAdvice() {
		System.out.println("afterAdvice()");
	}
}

  • AopMainClass02.java
package aop2;

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

import aop2.buz.Student;
import aop2.buz.Worker;

public class AopMainClass02 {

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

  • applicationCTX02.xml( aop + bean )

afterThrowingAdvice --> 오류 발생시 실행

<?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">
	
	<bean id="logAop" class="aop2.LogAop"></bean>
	<aop:config>
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut expression="within(aop2.buz.*)" id="pointcut1"/>
			<aop:around method="loggerAop" pointcut-ref="pointcut1"/>
		</aop:aspect>
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut expression="within(aop2.buz.*)" id="pointcut2"/>
			<aop:before method="beforeAdvice" pointcut-ref="pointcut2"/>
		</aop:aspect>
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut expression="within(aop2.buz.*)" id="pointcut3"/>
			<aop:after-throwing method="afterThrowingAdvice" pointcut-ref="pointcut3"/>
		</aop:aspect>
		<aop:aspect id="logger" ref="logAop">
			<aop:pointcut expression="within(aop2.buz.*)" id="pointcut4"/>
			<aop:after method="afterAdvice" pointcut-ref="pointcut4"/>
		</aop:aspect>
	</aop:config>
	
	<bean id="student" class="aop2.buz.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="aop2.buz.Worker">
		<property name="name" value="김유신"/>
		<property name="age" value="35"/>
		<property name="job" value="개발자"/>
	</bean>
</beans>

❌오류 발생시
afterThrowingAdvice 실행

⭕원래 결과




🔻och06_AOP3

[aop3.buz]


  • Student.java
package aop3.buz;

public class Student {
	private String name;
	private int age;
	private int gradeNum;
	private int classNum;
	
	public void getStudentinfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("학년 : "+getGradeNum());
		System.out.println("반    : "+getClassNum());

	}
	public void get3Studentinfo() {
		System.out.println("이름3 : "+getName());
		System.out.println("나이3 : "+getAge());
		System.out.println("학년3 : "+getGradeNum());
		System.out.println("반3  : "+getClassNum());
	}

	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;
	}
}

  • Worker.java
package aop3.buz;

public class Worker {
	private String name;
	private int age;
	private String job;
	
	public void getWorkerInfo() {
		System.out.println("이름 : "+getName());
		System.out.println("나이 : "+getAge());
		System.out.println("직업 : "+getJob());
	}

	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;
	}
}

[aop3 - Annotation]


  • LogAop.java

aspect / pointcut 선언

package aop3;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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 {
	// aop3.buz 패키지 안에 있는 모든 메소드
	@Pointcut("within(aop3.buz.*)")
	private void pointcutMethod() {
	}
	
	@Around("pointcutMethod()")
	public Object loggerAop(ProceedingJoinPoint joinpoint) throws Throwable {
		String signatureStr = joinpoint.getSignature().toString();
		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("within(aop3.buz.*)")
	public void beforeAdvice() {
		System.out.println("beforeAdvice()");
	}
	
	@After("within(aop3.buz.*)")
	public void afterAdvice() {
		System.out.println("afterAdvice()");
	}
}

  • AopMainClass03.java
package aop3;

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

import aop3.buz.Student;

public class AopMainClass03 {

	public static void main(String[] args) {
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX03.xml");
		
		Student student = ctx.getBean("student", Student.class);
		student.getStudentinfo();
		student.getStudentinfo();
		student.get3Studentinfo();
		
		ctx.close();
	}
}

  • applicationCTX03.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="aop3.LogAop"></bean>
	
	<bean id="student" class="aop3.buz.Student">
		<property name="name" value="홍길동"/>
		<property name="age" value="10"/>
		<property name="gradeNum" value="3"/>
		<property name="classNum" value="5"/>
	</bean>
</beans>

0개의 댓글