-
210629_1(Spring)Spring 2021. 6. 29. 18:18
설치및 세팅
1. jdk 설치되어 있어야 한다. ( JAVA_HOME, PATH, CLASSPATH 환경변수)
2. tomcat 설치 되어 있어야 한다.
3. eclipse jee 버전 설치
4. workspace 디렉토리생성 -- work_spring
5. 이클립스 실행시 workspace 연결
---기본준비
6. STS(Spring Tool Suite) 플러그인 설치
help- market place - spring 검색 - Spring Tools3 설치 - 설치후 재시작

스프링 개념
Spring : 용수철 : 쉽게 위어지고 복구되는 특징 ===> 유연하고 확장이 쉽게 다른 프레임워크(ibatis,,,)와
융합이 잘되는 개념
DI (dependency injection) : 의존성 주입
어떤 실행하고 있는 클래스가 참조하는 클래스를 직접 참조하여 인스턴스를 생성하는 것이아니라,
프레임워크(Spring)가 인스턴스를 생성하여 필요한 클래스에게 해당 인스턴스를 직접 주입하여 사용하는는 것임.
즉, 실행클래스는 참조클래스에 의존하지 않고 프레임워크에 의존하게 함으로
생성--호출--소멸 life cycle를 관리하도록 하는것
의존을 낮춤으로서, 유연성을 높이는 효과를 가져온다.
AOP (aspect oriented programming) : 관점 지향형 프로그래밍
어떤 함수(종단처리,핵심기능)가 시작 전에 또는 후에 특정 기능(횡단처리,공통기능)을 실행하도록 하는데
단, 기존의 소스는 건들지 않아야 한다.
spring MVC : Model View controller
스프링 프로젝트 생성하기
3가지 분류 : 1. 기본프로젝트생성하여, 스프링과 aspectj를 적용하는 방법 --xml많이 사용
ㄴ 스프링을 개발자패턴에 맞춤
2. 처음부터 스프링 프로젝트를 자동으로 생성하는 방법 -- @을 많이사용
ㄴ 개발자가 스프링 패턴에 맞추어야 한다.
3. 스프링부트 방식으로 생성하는 방법 -- 마치 응용프로그램 하듯이 개발
ㄴ 내부에서 개발구성을 해주어야 한다
AOP용어 정리
핵심관심 : Major Concern (예 : 게시판 글쓰기, 글보기, 글삭제, 글수정 ...)
횡단관심 : Cross-Cutting Concern (예 : 로깅, 인증, 예외처리 ...)
기존의 코드 : 핵심 관심과 횡단관심이 결합되어 있는 형태는
--> 유지보수 어려움이 있다 (중복발생, 생산성저하, 재사용힘듬, 변화힘듬)
code : 핵심 관심을 구현한것.
Advice : 횡단 관심을 구현한것.
Joinpoint : Advice가 Code에 끼어 들수 있는 순간들.
Pointcut : Joinpoint 중에서 실제 Advice가 Code에 끼어드는 순간.
Aspect : Advice + Pointcut
weaving : Code에 Aspect를 적용하는 과정.
Advice의 종류
Before advice : join point 이전에 실행이 되며
After returning advice : join point가 정상적으로 완료된 후에 실행이 됩니다.
예외를 던지는 상황은 정상적인 상황에서 제외된다.
Around advice : 메소드 호출과 같이 join point를 감싸는 Advice. 등등
Aspect와 SPRING을 적용하기 위한 SPRING TOOL SUITE설치
1) 기본 웹어플을 생성한다.
2) 웹어플에서 - Configure - convert to aspect Project -- aop 보조 플러그인(spring만으로도 구현가능)
convert to maven Project -- lib 자동관리 - 이게 더 중요하다
3) 이렇게 웹어플을 생성하고 나면 프로젝트 하단에 pom.xml이 생성된다.
4) https://mvnrepository.com/ 에 에 가서 maven용 lib 스크립트를 복사하여
pom.xml에 <dependencies> </dependencies>태그를 추가하고
바디에 붙여 넣고 저장하면 lib가 자동으로 추가된다.
또한 의존성있는 lib들도 역시 같이 추가된다.
주의) 같은 종류의 컴포넌트(lib)들은 버전이 같은 것으로 추가해야 된다.
Spring Context
Spring Web
Spring Web MVC
Spring JDBC
AspectJ Weaver
프로젝트 생성 오류시
src
build\classes
Webcontent
aspectj을 이용한 aop1
aspectj로 aop를 쉽게 구현할 수 있다.
package test.aspectj.aop; public class GilDong { private void say () { System.out.println("나는 홍길동 입니다."); } public static void main(String[] args) { // TODO Auto-generated method stub new GilDong().say(); } }package test.aspectj.aop; public aspect Advise { // 포인트 컷 적용지점을 설정한다. pointcut callsay(): call(* GilDong.say(..)); before() : callsay() { System.out.println("당신은 누구십니까?"); } after() : callsay(){ System.out.println("그러시군요~"); } }
spring을 이용해서 bean을 생성2
스프링에서는 이렇게 만든다
package test.spring.bean; public interface Greeting { void sayHi(); }package test.spring.bean; public class KoreanGreeting implements Greeting{ public void sayHi() { System.out.println("안녕 하시렵니까?"); } }package test.spring.bean; public class JapanGreeting implements Greeting{ public void sayHi() { System.out.println(" おはようございます"); } }package test.spring.bean; public class AmericanGreeting implements Greeting{ public void sayHi() { System.out.println("Hello Good morning~?"); } }<?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"> <bean id="korean" class="test.spring.bean.KoreanGreeting"/> <bean id="japan" class="test.spring.bean.JapanGreeting"/> <bean id="american" class="test.spring.bean.AmericanGreeting"/> </beans>package test.spring.bean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestFirstSpringBean { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ac = new ClassPathXmlApplicationContext(new String[] {"test/spring/bean/applicationContext.xml"} ); Greeting greeting = (Greeting) ac.getBean("korean"); greeting.sayHi(); greeting = (Greeting) ac.getBean("japan"); greeting.sayHi(); greeting = (Greeting) ac.getBean("american"); greeting.sayHi(); } }
Spring을 이용한 AOP 생성3
xml문서에서 namespace를 사용하는 이유는 하나의 xml문서에서 여러가지 종류(출처가다른)의 태그를 같이 사용하려면 namespace로 구별한다. 즉 태그가 서로 다른 접두어를 가지게 된다.
ex) <a:myTag /> <b:myTag /> 태그의 이름은 모두 myTag로 같지만 출신이 서로 다르다. 즉 다른 태그다.
포인트컷 기술 : () 인자가 없는, (.) 인자가 하나인, (..) 인자갯수에 상관이없는
실행순서
before : 당신의 이름을 말해보시오. <---advise
xxx이라고 합니다. <--- 메소드 실행 시점 기준
afterreturning : 아 멋진 분이군요. <---advise
afterSaying : 존경합니다. <---advise
메소드리턴값 : 난 ~~~ 이다.
package test.spring.aop; public class MannerAOP { public void beforeSaying() { System.out.println("당신의 이름을 말해 보시오"); } public void afterreturnSaying() { System.out.println("아 정말 멋진 분이군요!"); } public void afterSaying() { System.out.println("존경 합니다!"); } }package test.spring.aop; public interface Human{ public String sayName(String name); }package test.spring.aop; public class HongGilDong implements Human { @Override public String sayName(String name) { // TODO Auto-generated method stub System.out.println(name+"이라고 합니다."); return "난 동해번쩍 서해번쩍" + name +" 이다~"; } }package test.spring.aop; public class LeeSounSin implements Human { @Override public String sayName(String name) { // TODO Auto-generated method stub System.out.println(name+"이라고 합니다."); return "난 민족의 영웅" + name +" 이다~"; } }package test.spring.aop; public class YuGaunSun implements Human { @Override public String sayName(String name) { // TODO Auto-generated method stub System.out.println(name+"이라고 합니다."); return "난 민족의 횃불" + name +" 이다~"; } }<?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.xsd "> <!-- 빈생성 --> <bean id="hgd" class="test.spring.aop.HongGilDong" /> <bean id="lss" class="test.spring.aop.LeeSounSin" /> <bean id="ygs" class="test.spring.aop.YuGaunSun" /> <!-- advise 빈생성 --> <bean id="manner" class="test.spring.aop.MannerAOP" /> <!-- aop 적용 --> <aop:config> <aop:aspect ref="manner"> <aop:pointcut id="greeting" expression="execution(public * test.spring.aop.Human.sayName(..))"/> <aop:before pointcut-ref="greeting" method="beforeSaying" /> <aop:after-returning pointcut-ref="greeting" method="afterreturnSaying"/> <aop:after pointcut-ref="greeting" method="afterSaying"/> </aop:aspect> </aop:config> </beans><aop:before> 메소드 실행 전에 적용
<aop:after-returning> 메소드가 정상 실행된 후에만 적용
<aop:after-throwing> 메소드가 예외를 발생시킬 떄에만 적용 (catch문과 비슷)
<aop:after> 메소드가 실행된 후 무조건 적용(finally문과 비슷)
<aop:around> 모든 시점에 적용
Advise 설정에는 pointcut-ref 속성 말고 pointcut이란 속성도 있는데 pointcut 속성에는
<aop:pointcut> 태그의 expression 속성을 바로 설정해 줄 수 있다.
package test.spring.aop; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestSecondAOP { public static void main(String[] args) { // TODO Auto-generated method stub BeanFactory bf = new ClassPathXmlApplicationContext("test/spring/aop/aopAppContext.xml"); Human human = (Human) bf.getBean("hgd"); System.out.println(human.sayName("홍길동")); System.out.println(); human = (Human) bf.getBean("lss"); System.out.println(human.sayName("이순신")); System.out.println(); human = (Human) bf.getBean("ygs"); System.out.println(human.sayName("유관순")); System.out.println(); } }
포인트컷 기술2
@ 어노테이션을 이용하는 기술법 : 특징 xml의 사용량을 줄일수 있다.
import org.aspectj.lang.annotation.Aspect; 에서 제공하는
@Aspect <=== 아래클래스는 Aspect다. 즉 클래스 내부에 포인트컷과 어드바이스가 나온다.
클래스이름
import org.aspectj.lang.annotation.Pointcut;
@Pointcut <=== 포인트 컷 내용을 기술한다.(어느지점에 Advice가 적용할 것인지)
@Pointcut("execution(public * egovframework.rte.fdl.aop.sample.*Sample.*(..))")
execution(접근자 반환형 패키지.클래스.함수(인자))
() 인자가 없는, (.) 인자가 하나인, (..) 인자갯수에 상관이없는
주의) 반환형은 생략할 수 없다.
* 와일드 카드역할
@AspectJ의 pointcut 살펴보기
포인트컷(Pointcut) 정의하기
포인트컷은 결합점(joinpoints)을 지정하여 충고(advise)가 언제 실행될지를 지정하는데 사용된다.
Spring AOP는 Spring빈에 대한 메소드 실행 결합점만을 지원하므로, Spring에서 포인트컷은
빈의 메소드 실행점을 지정하는 것으로 생각할 수 있다.
다음 예제는 egovframework.rte.fdl.aop.sample 패키지 하위의 Sample명으로 끝나는 클래스의
모든 메소드 수행과 일치할 'targetMethod' 라는 이름의 pointcut을 정의한다.
@Aspect public class
AspectUsingAnnotation{ ...
@Pointcut("execution(public * egovframework.rte.fdl.aop.sample.*Sample.*(..))")
public void targetMethod( ){
//pointcut annotation 값을 참조하기 위한 dummy method
} ... }
포인트컷 지정자(designators)
execution(기술)
within(기술)
this
target
args
패키지..* : 하위의 모든클래스 포함
패키지.*.*() : 패키지아래 모든클래스의 모든메서드실행시점(하위포함X)
패키지..*.*() : 패키지아래 모든 결합점(joinpoint)
target(패키지.인터페이스) : 인터페이스를 구현하는 모든 클래스의 결합점
this(패키지.인터페이스) : 인터페이스를 구현하는 모든 프록시객체의 모든 결합점
연산자 : && || ! 도지원함
ㄴ프록시객체란?
핵심 기능 구현 객체들으 ㅣ실행시간을 파악하기 위하여 프록시 객체를 이용했다.
Proxy객체는 핵심 기능 외에 공통적인 기능을 담은 객체를 말한다.
이렇게 공통 기능 구현과 핵심 기능 구현을 분리하는것이 AOP의 핵심이다.
args(인자a) : 인자a를 갖는 모든 메서드 실행시점
@annotation(패키지.어노테이션클래스) : 특정 annotation을 적용한 클래스나 메서드
포인트컷 지정자( Designators)
Spring에서 포인트컷 표현식에 사용될 수 있는 지정자는 다음과 같다.
포인트컷은 모두 public 메소드를 대상으로 한다
excution : 메소드 실행 결합점(join points)과 일치시키는데 사용된다.
within : 특정 타입에 속하는 결합점을 정의한다.
this : 빈 참조가 주어진 타입의 인스턴스를 갖는 결합점을 정의한다.
target : 대상 객체가 주어진 타입을 갖는 결합점을 정의한다.
args : 인자가 주어진 타입의 인스턴스인 결합점을 정의한다.
@target : 수행중인 객체의 클래스가 주어진 타입의 어노테이션을 갖는 결합점을 정의한다.
@args : 전달된 인자의 런타임 타입이 주어진 타입의 어노테이션을 갖는 결합점을 정의한다.
@within : 주어진 어노테이션을 갖는 타입 내 결합점을 정의한다.
@annotation : 결합점의 대상 객체가 주어진 어노테이션을 갖는 결합점을 정의한다.
포인트컷 표현식 조합하기
포인트컷 표현식은 '&&', '||' 그리고 '!'를 사용하여 조합할 수 있다.
@Pointcut("execution(public * *(..))")
private void anyPublicOperarion( ){ }
@Pointcut("within(com.xyz.someapp.trading..*)")
private void inTrading( ) { }
@Pointcut("anyPublicOperation() || inTrading()")
private void tradingOperarion( ){ }
포인트컷 정의 예제
Spring AOP 에서 자주 사용되는 포인트컷 표현식의 예를 살펴본다.
Pointcut 선택된 Joinpoints execution(접근자 반환형 패키지.클래스.함수(가인자))
excution(public * *(..)) public : 메소드 실행
execution(* set*(..)) : 이름이 set으로 시작하는 모든 메소드명 실행
execution(* com.xzy.service.AccountService.*(..)) : AccountService인터페이스의 모든 메소드 실행
excution(* com.xyz.service.*.*(..)) service패키지의 모든 메소드 실행
excution(* com.xyz.service..*.*(..)) service패키지와 하위 모든 메소드 실행
within(com.xyz.service.*) service패키지 내의 모든 결합점
within(com.xyz.service..*) service패키지 및 하위 패키지의 모든 결합점
this(com.xyz.service.AccountService) AccountService 인터페이스를 구현하는 프록시 객체의 모든 결합점
target(com.xyz.service.AccountService) AccountService 인터페이스를 구현하는 대상 객체의 모든 결합점
@target(org.springframework.tansaction.annotation.Transactional)
대상 객체가 @Transactional 어노테이션을 갖는 모든 결합점
@within(org.springframework.tansaction.annotation.Transactional)
대상 객체의 선언 타입이 @Transactional 어노테이션을 갖는 모든 결합점
@annotation(org.springframework.tansaction.annotation.Transactional)
실행메소드가 @Transactional 어노테이션을 갖는 모든 결합점
@args(com.xyz.security.Classified)
단일 파라미터를 받고, 전달된 인자 타입이 @Classifired 어노테이션을 갖는 모든 결합점
bean(accountRepository) "accountRepository" 빈
!bean(accountRepository) "accountRepository" 빈을 제외한 모든 빈
bean(*) 모든빈
bean(account*) 이름이 'account'로 시작되는 모든 빈
bean(*Repository) 이름이 "Repository"로 끝나는 모든 빈
bean(account/*) 이름이 "account/"로 시작하는 모든 빈
bean(*dataSource) || bean(*DataSource) 이름이 "dataSource"나 "DataSource"으로 끝나는 모든 빈
'Spring' 카테고리의 다른 글
210706_1(iBatis) (0) 2021.07.06 210705_2(iBatis) (0) 2021.07.05 210702_1(Spring) (0) 2021.07.02 210701_1(Spring_DI적용하기) (0) 2021.07.01 210630_1(Spring) (0) 2021.06.30