160621: 68회차
Programming
2016. 6. 21. 16:21
종료하기 전 티스토리 네이버 로그아웃 할 것
1. 툴
동일
추가시:
2. 폴더
동일
추가시:
3. 사용할 사이트
동일
추가시:
4. 공부하는 것
[05][Spring] AOP(Aspect Oriented Programming)의Transaction 구현(댓글있는 글 삭제)
1. AOP(Aspect Oriented Programming)의 구현

-----------------------------------------------------------------------------------------------------------------------


1) AOP 소개 (관점 지향 프로그래밍)
- 관점 지향 프로그래밍(AOP)은 객체지향을 잇는 또 하나의 프로그래밍 언어 구조라고
할 수 있습니다.
할 수 있습니다.
- AOP는 OOP를 좀더 OOP답게 만들어줄 수 있습니다.
- 핵심 관심 사항(core concern) : 핵심 비즈니스 기능
- 공통 관심 사항(cross-cutting concern) : 어플리케이션 전반에 걸쳐 적용되는 공통
기능
기능
- 은행 업무에서 계좌이체, 이자계산, 대출 처리는 주된업무임으로 핵심 관점(핵심 비즈니스)으로
볼수 있습니다.
이런 업무를 처리하는데 있어서 '로깅', '보안','트랜잭션' 등의 처리는 어플리케이션
전반에 걸처 필요한 기능으로서 핵심기능과 구분하여 공통 관심 사항
(Cross-Cutting Concern)이라고 합니다.
볼수 있습니다.
이런 업무를 처리하는데 있어서 '로깅', '보안','트랜잭션' 등의 처리는 어플리케이션
전반에 걸처 필요한 기능으로서 핵심기능과 구분하여 공통 관심 사항
(Cross-Cutting Concern)이라고 합니다.
- AOP에서는 공통 관심 사항을 1) 하나의 클래스 단위(aspect)로 모으고 분리함으로써
재이용성과 보수성을 높이고 있습니다.
재이용성과 보수성을 높이고 있습니다.
- 2) 보안이나 트랜잭션과 같은 공통 기능을 별도의 모듈로 구현한 뒤, 분리하지 않고
각기능을 필요로 하는 곳에 사용하게 되는 경우 각모듈과 이를 포함하고 있는
공통 모듈 사이에는 의존관계가 형성되며, 공통 모듈을 사용하는 클래스가 많아질
경우 의존관계는 점점 복잡해집니다.
또한 공통모듈을 사용하는 코드가 여러곳에서 중복되는 문제점도 발생합니다.
각기능을 필요로 하는 곳에 사용하게 되는 경우 각모듈과 이를 포함하고 있는
공통 모듈 사이에는 의존관계가 형성되며, 공통 모듈을 사용하는 클래스가 많아질
경우 의존관계는 점점 복잡해집니다.
또한 공통모듈을 사용하는 코드가 여러곳에서 중복되는 문제점도 발생합니다.
- AOP를 적용할 경우 핵심로직을 구현한 클래스는 더 이상 여러 공통 모듈을 의존하지
않습니다, 즉 핵심로직 구현클래스에서 공통모듈을 사용하는 코드를 포함하지
않습니다.
않습니다, 즉 핵심로직 구현클래스에서 공통모듈을 사용하는 코드를 포함하지
않습니다.

---------------------------------------------------------------------------------------------------------------------------

실제 공통 관심 사항 코드가 모듈 안에 구현되어져 있다
코드화되어서 있는 것
-----------------------------------------------------------------------------------------------------------------------------

근데 얘는 코드화되어져 있는 기능을 따로 뺄 수 있는 것
이런 공통 사항을 AOP 프레임워크에다가 빼놓고 있다가 실질적으로 실행이 되어질 때
합쳐서 실행하는 것
이게 aop의 횡단적 산재를 분리
-----------------------------------------------------------------------------------------------------------------------
2) AOP 주요 용어

- Advice : 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의합니다.
예)메서드 호출하기 전또는 후(언제)에 트랜잭션을 시작한다(공통 기능)처럼 기능을
적용 한다는 것을 정의 합니다.
적용 한다는 것을 정의 합니다.
- Joinpoint : Advice를 적용할 수 있는곳을 말합니다. 애플리케이션 실행에 aspect를
끼워넣을 수 있는 지점(point)을 말합니다. 메서드 호출, 필드값 변경 등이
Joinpoint에 해당 합니다
Joinpoint에 해당 합니다
- Pointcut : 여러 개의 Joinpoint 들 중에서 실제로 Advice가 적용되는 Joinpoint 를
나타냅니다. 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수
있습니다.
- Weaving : Advice를 핵심로직 코드에 적용하는 것을 '위빙'이라 부릅니다.
위빙의 시점에 프록시 객체를 생성하며, Target 객체의 3개의 시점중에 한곳에서
이루어집니다.
. 컴파일 시 - 컴파일시에 코드를 삽입하는 방법으로 AspectJ에서 사용하는 방식
별도의 컴파일러가 필요함
. 클래스 로딩시 - 클래스가 JVM에 적재될 때 적용하며 AspectJ에서 지원함
. 런타임 시 - 애플리케이션이 실행 중에 aspect가 적용됨 프록시 객체를 이용하여
적용됨, 스프링에서 사용함. (***)
- Target : 핵심 로직을 구현하는 클래스를 말합니다.
- Aspect : 여러 객체에 공통으로 적용되는 공통 관점 사항을 말합니다.
Advice 와 Pointcut 을 합친것이라 할 수 있으며, Aspect 가 무엇을 언제 어디서
할지의 모든 정보가 정의됩니다.
할지의 모든 정보가 정의됩니다.
- Proxy : Advice를 Target객체에 적용하면 생성되는 객체입니다.

클라이언트는 비즈니스 로직만 호출
프록시가 비즈니스 로직에 필요한 공통관심사 호출 처리
트랜잭션 - 원자성
1)
2)
3)
라는 구성이 있지만
하나의 job으로 묶여있어서 분리 불가능한 것
- 핵심 관심 사항(core concern) : 핵심 비즈니스 기능
- 공통 관심 사항(cross-cutting concern) : 어플리케이션 전반에 걸쳐 적용되는 공통
기능
1) 클라이언트가 비즈니스 로직(business())을 호출함
2) 프록시가 공통관심사항 로직(cross-cutting concern)을 호출함
3) 프록시가 다시 한번 비즈니스 로직을 호출함
4) 핵심 관심 사항(core concern)에서 프록시에게 값을 전달함
5) 프록시가 공통관심사항 로직을 호출함
6) 프록시가 클라이언트에게 로직 결과값을 전달함
관점 지향 프로그래밍
위키백과, 우리 모두의 백과사전.
![]() | 이 문서의 내용은 출처가 분명하지 않습니다. (2013년 9월) |
관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)은 컴퓨팅에서 메인 프로그램의 비즈니스 로직으로부터 2차적 또는 보조 기능들을 고립시키는 프로그램 패러다임이다. 이것은 횡단관심사의 분리를 허용하고, 관점 지향 소프트웨어 개발의 기초를 형성하여 모듈화를 증가시키려 한다. 관점 지향 소프트웨어 개발이 모든 엔지니어링 분야에 관련되는 반면에, 관점 지향 프로그래밍은 소스코드 레벨에서 관심사들의 모듈화를 지원하는 프로그래밍 기술과 툴들을 포함한다.
관점 지향 프로그래밍은 프로그램을 명확한 부분으로 나누는 것을 수반한다. 모든 프로그래밍 패러다임은 이들 관심사들을 구현, 추상화, 구성하는 추상적 개념을 제공하는 분리되고, 독립적인 통로들을 통해 Grouping의 같은 레벨과 관심사들의 캡슐화(Encapsulation)를 지원한다. 그러나 어떤 관심사들은 구현의 이런 형태를 거역하고, 이들이 프로그램 내에서 다중 추상적 개념들에 영향을 끼치기 때문에 횡단관심사(cross-cutting concerns)라고 불린다.
스프링을 쓰는 곳에서는 이거 물어볼 수도 있음
3) Spring의 AOP
- Spring에서 AOP는 런타임시에 AOP를 적용하므로 소스코드나 클래스 정보를 변경
하지 않습니다.
하지 않습니다.
- Spring에서 AOP는 프록시를 이용하여 AOP를 적용합니다.
프록시 기반 AOP는 핵심로직을 구현한 객체에 직접 접근하는 것이 아니라
중간에 프록시를 생성하여 프록시를 통해서 핵심로직을 구현한 객체에 접근하게
됩니다. (프록시 호출 그림 참조 )
됩니다. (프록시 호출 그림 참조 )
- 프록시 기반에서는 메서드 호출때에만 Advice를 적용할 수 있습니다.
필드값 변경과 같은 Joinpoint에 대해서는 적용할 수 없습니다.
- Spring은 다음 네개의 형태로 AOP를 지원함
1) 프록시 기반 AOP(스프링 모든 버전에서 지원)
2) @AspectJ 애너테이션 기반 애스펙트(스프링2.0부터 지원)
3) 순수 POJO 애스펙트(스프링2.0부터 지원)
4) AspectJ 애스펙트에 빈 주입(스프링 모든 버전에서 지원)
4) AOP Transaction 를 적용한 댓글 있는 게시판 글 삭제하기
- 댓글이 있는 게시판 글을 삭제하면 부모를 참조하는 자식레코드가 있으므로 삭제가
안됩니다.
안됩니다.
- 자식레코드 삭제후 부모레코드를 삭제합니다.
- 두개의 작업을 Transaction을 이용해서 작성합니다. - 두 개의 작업을 하나의 job으로 만듬(트랜잭션)
- 일반 작업프로세스 : controller -> dao -> mybatis -> oracle
- 트랜잭션을 적용한 작업프로세스 : controller -> service -> dao -> mybatis ->oracle
ㄴ여기서 서비스패턴을 쓴당
- Service 패턴을 적용해서 트랜잭션을 위한 BbsService.java 생성합니다.
>>>> BbsService.java
package spring.model.bbs;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BbsService {
@Autowired
// private BbsDAO dao;
private BbsDAO_Mybatis dao;
@Autowired
private ReplyDAO rdao;
public void delete(int bbsno) throws Exception{
rdao.delete(bbsno);
dao.delete(bbsno);
}
}
- Transaction 설정 <aop:config> 있는곳에 Target beans과 pointCut 메소드가 있는 빈설정이 있어야 합니다.
>>>> root-context.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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- Transaction Manager -->
//트랜잭션 매니저를 참조하고 있는 트랜잭션친구들을 선언해놔야 하는것
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="delete" rollback-for="Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="transactionPointcut" expression="execution(* spring.model.bbs.*Service.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPointcut" />
</aop:config>
<context:component-scan base-package="spring.model.*" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/>
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
컨피그 태그와 컴포넌트 속성을 같은 곳에 둬야 인식을 함! :>
>>>> servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- <context:component-scan base-package="spring.sts.blog" /> -->
<!-- <context:component-scan base-package="spring.model.*" /> -->
<context:component-scan base-package="spring.sts.blog" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans:beans>
>>>> pom.xml
<!-- 인터페이스없이 transaction사용시 에러예방 -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.1</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!-- aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
>>>> BbsController.java
@Autowired
private BbsService service; //추가
@RequestMapping(value="/bbs/delete",method=RequestMethod.POST)
public String delete(int bbsno,String passwd,String nowPage,String word, String col,Model model){
int pwcnt = dao.checkPasswd(bbsno, passwd);
String url = "./error/passwdError";
if(pwcnt==1){
try{
// rdao.bdelete(bbsno);//게시판글의 댓글들 삭제
// dao.delete(bbsno);//게시판글 삭제
service.delete(bbsno); // 위에 기능 중 하나가 실패하면 다른 애들 삭제도 취소하는것
model.addAttribute("nowPage", nowPage);
model.addAttribute("word", word);
model.addAttribute("col", col);
url = "redirect:./list";
}catch(Exception e){
e.printStackTrace();
url = "./error/error";
}
}
return url;
}
>>>>>> ReplyDAO.java (댓글 삭제:생략가능)
public boolean bdelete(int bbsno){
boolean flag = false;
int cnt = sqlSessionTemplate.delete("reply.bdelete", bbsno);
if(cnt>0) flag = true;
return flag;
}
>>>> reply.xml (정상)
<delete id="bdelete" parameterType="int">
delete from REPLY
where bbsno = #{bbsno}
</delete>
- Service단에서 Transaction을 적용하기위해 BbsDAO의 delete에서 오류 발생시킵니다.
>>>>>> bbs.xml
<delete id="delete" parameterType="int">
delete FROM bbs
WHERE bbsno1 = #{bbsno}
</delete>
>>>> views/error/error.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<script type="text/javascript">
alert("현재페이지에 에러가 발생했습니다.");
history.back();
</script>
AOP라서 모델1에서는 사용불가
5. 수업
진도:
hw:
6. 할것
망전인벤-헤기 스킬트리
럭키 - 인스타 볼 것
http://www.inven.co.kr/board/powerbbs.php?come_idx=4418&l=3953
'Programming' 카테고리의 다른 글
160623: 70회차 (0) | 2016.06.23 |
---|---|
160622: 69회차 (0) | 2016.06.22 |
160620: 67회차 (0) | 2016.06.20 |
160617: 66회차 (0) | 2016.06.17 |
160616: 65회차 (0) | 2016.06.16 |