@Configuration
: 설정파일을 만들기 위한 어노테이션 or Bean을 등록하기 위한 어노테이션.
@Bean
: 개발자가 직접 제어가 불가능한 라이브러리를 사용할때, 초기설정을 하기위해 사용.
@Component
: 개발자가 직접 개발한 클래스를 Bean으로 등록하고 싶을땐 해당 어노테이션을 사용.
package env03;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class AdminConnection implements DisposableBean, InitializingBean {
private String adminId;
private String adminPw;
private String sub_adminId;
private String sub_adminPw;
public void afterPropertiesSet() throws Exception {
System.out.println("AdminConnection afterPropertiesSet() 생성자 생성이후...");
}
public void destroy() throws Exception {
System.out.println("AdminConnection destroy() 소멸자 소멸전...");
}
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
: 환경작업시 사용
@Bean
: bean 설정
admin3.properties
, sub_admin3.properties
를 읽음adminConnection.setAdminId(adminId);
adminConnection.setAdminPw(adminPw);
adminConnection.setSub_adminId(sub_adminId);
adminConnection.setSub_adminId(sub_adminSw);
@Bean
은 xml에서 <Bean>
한것과 같다.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
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;
}
}
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();
}
}
<?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>
<property name="portNum" value="8181"></property>
</bean>
</beans>
<?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.98"></property>
<property name="portNum" value="8080"></property>
</bean>
</beans>
: Aspect Oriented Programming
1) 관점 지향 프로그램(Aspect Oriented Programming, AOP)의 정의
Core Concern 핵심관심
Business 업무. 핵심 기능, 가치
Cross-cutting 횡단관심
부가적인 요구사항. 보안, 인증, 로그작성, 정책적용 등
Aspect
흩어진 관심사(Crosscutting Concerns)를 묶어서 모듈화 한 것.
하나의 모듈. Advice와 Point Cut이 들어간다.
특정 관심사에 관련된 코드만을 캡슐화
Target
Aspect가 가지고 있는 Advice가 적용되는 대상(클래스, 메서드 등등)을 말한다.
Advice
어떤 일을 해야할 지에 대한 것. 해야할 일들에 대한 정보를 가지고 있다.
Join Point
가장 흔한 Join Point는 메서드 실행 시점.
Advice가 적용될 위치, 끼어들 수 있는 지점. 생성자 호출 직전, 생성자 호출 시, 필드에 접근하기 전, 필드에서 값을 가져갔을 때 등등.
Point Cut
Join Point의 상세한 스펙을 정의한 것.
어디에 적용해야 하는지에 대한 정보를 가지고 있다. “A 클래스에 B 메서드를 적용할 때 호출을 해라.”와 같은 구체적인 정보를 준다.
Weaving
Join Point에 해당하는 Advice를 삽입하는 과정.
Aspect와 핵심 관심사를 엮는 것(weave)
Before
,After Returning
,After Throwing
,After
,Around
xml 스키마기반, @Aspect 애노테이션 기반 으로 사용 할 수 있다.
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;
}
}
joinpoint
package aop1;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogAop {
// Around Advice에서 사용할 공통기능 메서드는,대부분 파라미터로 전달받은
// 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 Millis
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();
}
}
aop, beans를 찍고 생성
<aop:pointcut expression="within(aop1.S*)" id="pointcut1"/> 로 변경하면
<?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 name="student" class="aop1.Student">
<property name="name" value="연개소문"></property>
<property name="age" value="50"/>
<property name="gradeNum" value="3"/>
<property name="classNum" value="5"/>
</bean>
<bean name="worker" class="aop1.Worker">
<property name="name" value="이순신"/>
<property name="age" value="35"/>
<property name="job" value="개발자"/>
</bean>
</beans>
och06_AOP2 | aop2 | aop2.buz(비즈니스) |
aop1
student.java
복붙 +어쩌다 오류
부분 추가
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;
}
}
aop1
Worker.java
그대로 복붙
package aop2;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogAop {
public Object loggerAop(ProceedingJoinPoint joinPoint) throws Throwable {
// 핵심 업무에 사용 method
String signatureStr = joinPoint.getSignature().toShortString();
long st = System.currentTimeMillis();
System.out.println(signatureStr + "is start..");
try {
// 핵심업무 수행 aop2.buz.Stuent.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();
}
}
<?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-returning method="afterReturningAdvice" pointcut-ref="pointcut4"/>
</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>
<property name="age" value="10"></property>
<property name="gradeNum" value="3"></property>
<property name="classNum" value="5"></property>
</bean>
<bean id="worker" class="aop2.buz.Worker">
<property name="name" value="김유신"></property>
<property name="age" value="35"></property>
<property name="job" value="개발자"></property>
</bean>
</beans>
och06_AOP3 - aop3 , aop3.buz
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;
}
}
이전꺼 복붙해서 사용
@Aspect
,@Around
,@Before
,@After
은
02장에서 한<aop:after>, <aop:aspect>, <aop:around>, <aop:before>
와 같다.
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().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("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();
}
}