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;
}
}
@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;
}
}
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();
}
}
admin.id=super
admin.pw=12345
sub_admin.id=sub3
sub_admin.pw=67890
🔎xml / anntation 비교
위-xml / 아래-annotation
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;
}
}
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();
}
}
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>
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(Aspect Oriented Programming)
joinpoint - 핵심관심사가 들어가는 지점
Around를 많이 씀
porm.xml -> aspectjweaver - aop
핵심 관심사 - Student, Worker
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;
}
}
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;
}
}
퍼포먼스 측정
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));
}
}
}
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();
}
}
- 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.*)" 다시되돌리면?
핵심 관심사 - 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;
}
}
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;
}
}
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()");
}
}
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();
}
}
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 실행
⭕원래 결과
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;
}
}
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;
}
}
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()");
}
}
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();
}
}
<?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>