카테고리 없음

0305 오전수업

logloglog 2021. 3. 5. 09:28

***등록전에 파라미터에 관한 이슈

 

일단

멤버컨트롤러

@RequestMapping(value = "/regist", method = RequestMethod.POST)
	   public void regist(MemberRegistCommand memberReq, HttpServletRequest request, 
	                  HttpServletResponse response) throws SQLException, IOException {

	      MemberVO member = memberReq.toMemberVO();
	      memberService.regist(member);

	      response.setContentType("text/html;charset=utf-8");
	      PrintWriter out = response.getWriter();
	      out.println("<script>");
	      out.println("alert('회원등록이 정상적으로 되었습니다.');");
	      out.println("window.opener.location.href='" + request.getContextPath() + "/member/list.do';");
	      out.println("window.close();");
	      out.println("</script>");

	      if (out != null)
	         out.close();
	   }
	

 

 

멤버레지스트커맨드 만들러 가자

>>사용자 화면의 데이터를 그대로 받을 수 있도록 만드는것

 

 

Q. 서브밋할떄 이벤트걸수있으니까 가공해서 넘겨도되지않으까??

그럼 자바스크립트에서 조작을 해야함. 이게 매칭이안됨. 사용자의 화면단에서 입력되는 데이터를 모델ㄹ링을 해서 어떻게 넘어올지 알아ㅑ야하는데 중간 자바스크립트가 끼어들어버리면 한번 더 봐야하는 불편함이 생김 (화면을 못믿게됨)

또 js가 클래스로 구현되는것도 아니고, 자바처럼 클릭해서 타고갈수도없어서 매우불편

자꾸 여기저기 산발적으로 데이터가공을 해놓으면 수습이 안됨

이거랑 비슷한 역할을 하는게 디비의 프로시저임. 이걸 어디 적어두지않구 숨겨져잇음 (js마냥..)

나는 똑같이 테이블에 넣엇는데 자꾸 데이터값이 바껴서 들어감 (프로시저를 해놔가지고)

 

그래서 사전에, 정해야함. 테이블설계와화면설계가 끝남과 동시에

화면에서 만들어지는 파라미터 데이터 = 테이블 과 맞는가??

화면명세에서 가장 필요한건 전달되는 파라미터테이블에 사상시킨 VO랑 비교해서 다르다면 커맨드로 어떻게 조작하자까지 논의가 끝나야함

 

결론 데이터가공은 컨트롤러나 서비스쪽에서만 한다고 기준을 딱 정해야함

 

VO는 테이블에 맞춰서 만들지만

커맨드는 기준이 화면

화면의 데이터를 모두 받을수있게 >> 그래서 폰이 배열임

 

커맨드객체는 vo로 변환시킬수잇는 메서드를 내장시키는게 보통임

 

>>>커맨드로 파라미터 받고 이걸 vo로 바꾸는거임

얘가 가진 정보를 최대한 vo에 맞게 넣어주는거임 (매퍼역할)

 

package kr.or.ddit.command;

import java.util.Arrays;

import kr.or.ddit.dto.MemberVO;

public class MemberRegistCommand {

	String id;
	String pwd;
	String email;
	String picture;
	String authority;
	String name;
	String[] phone;
	
	
	
	public String getId() {
		return id;
	}



	public void setId(String id) {
		this.id = id;
	}



	public String getPwd() {
		return pwd;
	}



	public void setPwd(String pwd) {
		this.pwd = pwd;
	}



	public String getEmail() {
		return email;
	}



	public void setEmail(String email) {
		this.email = email;
	}



	public String getPicture() {
		return picture;
	}



	public void setPicture(String picture) {
		this.picture = picture;
	}



	public String getAuthority() {
		return authority;
	}



	public void setAuthority(String authority) {
		this.authority = authority;
	}



	public String getName() {
		return name;
	}



	public void setName(String name) {
		this.name = name;
	}



	public String[] getPhone() {
		return phone;
	}



	public void setPhone(String[] phone) {
		this.phone = phone;
	}






	@Override
	public String toString() {
		return "MemberRegistCommand [id=" + id + ", pwd=" + pwd + ", email=" + email + ", picture=" + picture
				+ ", authority=" + authority + ", name=" + name + ", phone=" + Arrays.toString(phone) + "]";
	}
	
	public MemberVO toMemberVO() {
		String phone="";
		for (String data: this.phone) {
			phone += data;
		}
		
		//MemberVO setting
		MemberVO member = new MemberVO();
		member.setId(id);
		member.setPwd(pwd);
		member.setPhone(phone);
		member.setEmail(email);
		member.setPicture(picture);
		member.setAuthority(authority);
		member.setName(name);
		member.setRegDate(new Date());
        
		return member;
	}
	
}

ㅇㅒ가 넣어준 데이터를 어떻게 할지는 서비스에서 검증을 하든지 뭘하든지 결정을 하는거고

코맨드는 최대할 ㅅ할수있는만큼 해서 주는거임

 

regDate도 저게 디비에 바로 가는게 아니고 걍 일단 초ㅣ대한 줄수잇는만큼 다 줘보는거임

 


 

다시 멤버컨트롤러

@RequestMapping(value = "/regist", method = RequestMethod.POST)
	   public void regist(MemberRegistCommand memberReq, HttpServletRequest request, 
	                  HttpServletResponse response) throws SQLException, IOException {

	      MemberVO member = memberReq.toMemberVO();
	      memberService.regist(member);

	      response.setContentType("text/html;charset=utf-8");
	      PrintWriter out = response.getWriter();
	      out.println("<script>");
	      out.println("alert('회원등록이 정상적으로 되었습니다.');");
	      out.println("window.opener.location.href='" + request.getContextPath() + "/member/list.do';");
	      out.println("window.close();");
	      out.println("</script>");

	      if (out != null)
	         out.close();
	   }

 

파라미터를 다 MemberRegistCommand 인 memberReq로 받겟다는 얘기임

 

location href에서 컨텍스트패스쳐야해서 리퀘스트 받은거고 스크립트 동적으로 내보내야하니까 리스폰스 받은거임

 

닫으면 리스트

 


디테일로 넘어가자

 

detail.jsp 가져오기

세개 다 한번에 가져와버리자

시나리오:

아이디 받아서 (파라미터에서 스트링아이디) 서비스 호출해서 겟멤버 다녀왓다가

받은걸 모델에 심고 해당 유알엘 리턴하면 됨

 

멤버컨트롤러

	@RequestMapping(value="/detail", method=RequestMethod.GET)
	public String detail(String id, Model model) throws SQLException{
		String url = "member/detail";
		MemberVO member = memberService.getMember(id);
		model.addAttribute("member",member);
		
		return url;
	}
	

 

모델은 어댑터가 넘겨준거임

그래서 여기선 심어주기만 하면 되는거임

 

모델엔뷰를 안쓰구 모델을 쓴 이유? 걍 안쓴거임 써도됨

상세화면 보이면 됨


modify

 

디테일과다른것은

이부분 나머지는 같다

 

수정창이뜬다


*디테일에 사진이 안나옴

(본래 있던 사진은 나오는데 새로 등록한게 안나옴)

원인 : 데이터가 두개들어감!!!! 

등록화면에서 업로드를 시키면

1개
2개

두개임

같은 이름 파라미터 2개는 배열로 들어감

그럼 디비를 보면 

두개임 
이놈 지우기
이제 새로등록한것도 된다.


다시 수정

 

수정화면의 시나리오

: 레스트로 햇던 업로드의 폼태그가 파라미터로 들어옴

 

사진변경 눌러서 사진을 변경하면

사진을 새 사진으로 바꾸고, 기존의 파일은 인풋태그의 text  oldpicture에 들어감

 

이 3개인자가 추가된다. 변경된사진은 2에들어오고 기존의 파일명은 1에 들어옴 3은 잘못한거고 4는 temppicture (이전에 올렷던 사진 파일명 보여주려고 하는거임)

1,2,4 3개가 넘어감

 

이걸 받아야함

멤버VO론 이걸 못받음 이런성분이없음

 

>>modify에 잇는 파라미터 데이터를 모두 받을수잇는 모디파이커맨드를 따로 만들겟다

파일이 변경되었다면 저장도 진행해야함

 

 

멤버컨트롤러

모디파이에 대한 서브밋을 받아야하니까

@RequestMapping(value="/modify", method=RequestMethod.POST)

 

커맨드객체만들러

얘는 화면중심으로 만든다.

 

23분.... enctype 멀티파트랑 3가지 충족되어야 이렇게 받을수잇다....

해당 멤버VO를 만들어주는 사명이잇다 (최대한 할수잇는부분까지)

근데 파일은 어케할수가없음 

왜냐면 저장할떄 네임바뀔꺼니까 저장을 해야 네임알수잇는거라..

package kr.or.ddit.command;

import java.util.Date;

import org.springframework.web.multipart.MultipartFile;

import kr.or.ddit.dto.MemberVO;

public class MemberModifyCommand {

	private String id;					//아이디
	private String pwd;					//패스워드
	private String name;				//이름
	private String phone;				//전화번호
	private String email;				//이메일
	private MultipartFile picture;		//사진파일
	private String oldPicture;			//이전 사진 파일명
	private String uploadPicture;		//변경된 사진 파일명
	private String authority;			//권한
	
	public String getAuthority() {
		return authority;
	}
	public void setAuthority(String authority) {
		this.authority = authority;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public MultipartFile getPicture() {
		return picture;
	}
	public void setPicture(MultipartFile picture) {
		this.picture = picture;
	}
	public String getOldPicture() {
		return oldPicture;
	}
	public void setOldPicture(String oldPicture) {
		this.oldPicture = oldPicture;
	}
	public String getUploadPicture() {
		return uploadPicture;
	}
	public void setUploadPicture(String uploadPicture) {
		this.uploadPicture = uploadPicture;
	}
	
	@Override
	public String toString() {
		return "MemberModifyCommand [id=" + id + ", pwd=" + pwd + ", name=" + name + ", phone=" + phone + ", email="
				+ email + ", picture=" + picture + ", oldPicture=" + oldPicture + ", uploadPicture=" + uploadPicture
				+ ", authority=" + authority + "]";
	}

	
	public MemberVO toParseMember() {
		
		//MemberVO setting
		MemberVO member = new MemberVO();
		member.setId(id);
		member.setPwd(pwd);
		member.setName(name);
		member.setPhone(phone.replace("-", ""));
		member.setEmail(email);
		member.setAuthority(authority);
	
		return member;
	}
	
	
	
}

 

*실제로는 파일이 오는 부분에서는 따로 트림을 해줘야함 (필터로/..?)

 

이제 모디파이쪽의 시그니처를 만들ㅇ수잇음

 

멤버컨트롤러

@RequestMapping(value="/modify", method=RequestMethod.POST)
	public void modify(MemberModifyCommand modiReq, HttpSession session, HttpServletResponse response) throws Exception{
		
	}

리스펀스는 왜받음? 포워딩ㅇ이나 센드리다이렉트할화면없고 스크립트내보내겟다는 얘기임

세션은 왜받음? 수정한내용이 로그인한사람의 것이면 사용자가 새고안해도 로그인한 유저의 정보를 고쳐줘야하기떄문

 

처리

1. 멤버vo 끄집어내기

 

 

2. 파일처리 (파일변경 없을 시 기존 파일명 유지)

아까 save picture regist 만든..

올드픽쳐 지우고 멀티 저장ㄷ이 되는.....놈

파일 수정안하면 멀티파트파일이 널이니까 널임

 

-신규파일 변경 및 기존파일 삭제

String fileName = savePicture(modiReq.getOldPicture(), modiReq.getPicture());
		member.setPicture(fileName);
		

업로드파일에 인자가있/없을 꼭 확인해야 수정안한채로 그냥 햇는때 널이되는사태를 막을수잇다.

 

그래서 이작업을 꼭 해줘야함. 파일변경 없을 시 기존 파일명 유지

 

암튼 사진변경을 안했따라는 걸 반드시 비교해서 변경하지않았따면 기존파일을 넣어줘야한다는거!

 

 

3. 서비스

memberService.modify(member);

 

4. 로그인한 사용자의 경우 수정된 정보로 session 업로드

MemberVO loginUser = (MemberVO) session.getAttribute("loginUser");
		if(loginUser != null && member.getId().equals(loginUser.getId())) {
			session.setAttribute("loginUser", member);
		}

로그인 유저를 세션에서 꺼내서 로긴한사람아이디=수정한사람ㅇ아이디 비교해서 같으면

변경된 내용으로 세션 바꿔치기

 

@RequestMapping(value="/modify", method=RequestMethod.POST)
	public void modify(MemberModifyCommand modiReq, HttpSession session, HttpServletResponse response) throws Exception{
		MemberVO member = modiReq.toParseMember();
		
		String fileName = savePicture(modiReq.getOldPicture(), modiReq.getPicture());
		member.setPicture(fileName);
		
		if(modiReq.getPicture().isEmpty()) {
			member.setPicture(modiReq.getOldPicture());
		}
		
		memberService.modify(member);
		
		MemberVO loginUser = (MemberVO) session.getAttribute("loginUser");
		if(loginUser != null && member.getId().equals(loginUser.getId())) {
			session.setAttribute("loginUser", member);
		}
		
	}

 

5.

이제 사용자 화면 고쳐야함

수정됏으니까 디테일로 돌아가긴 하되 리다이렉트를 시켜야하는데

센드리다이렉트하면 메세지를 못주니까

수정되엇읍니다 주려고 스크립트적어야하니까 response.out 한거임

 

jsp 만들어서 포워딩하는게 더  추천하는 방법이긴함

response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		String output = "" + "<script>" + "alert('수정되었습니다.');" +"location.href='detail?id="
		+ member.getId() + "';"
		+ "window.opener.parent.location.reload();" + "</script>";
		out.println(output);
		out.close();
@RequestMapping(value="/modify", method=RequestMethod.POST)
	public void modify(MemberModifyCommand modiReq, HttpSession session, HttpServletResponse response) throws Exception{
		MemberVO member = modiReq.toParseMember();
		
		String fileName = savePicture(modiReq.getOldPicture(), modiReq.getPicture());
		member.setPicture(fileName);
		
		if(modiReq.getPicture().isEmpty()) {
			member.setPicture(modiReq.getOldPicture());
		}
		
		memberService.modify(member);
		
		MemberVO loginUser = (MemberVO) session.getAttribute("loginUser");
		if(loginUser != null && member.getId().equals(loginUser.getId())) {
			session.setAttribute("loginUser", member);
		}
		
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
		String output = "" + "<script>" + "alert('수정되었습니다.');" +"location.href='detail?id="
		+ member.getId() + "';"
		+ "window.opener.parent.location.reload();" + "</script>";
		out.println(output);
		out.close();
		
	}

 

 

*오류

모디파이_js

펑션안의 펑션떔시

 

//회원 수정 submit
function modify_go(){
	//alert("modify btn click");
	var form=$('form[role="form"]');	
	form.submit();
}

얘 잘라내서

 

모디파이.jsp 에 밖으로빼기

수정된다!

 

근디 수정한다음에 닫기버튼이 안먹음

왜???

수정 된 다음에 오프너의 패런츠의 로케이션을 리로드시키는데 리로드시켜버리면

 

커먼js에

 

이 오프너로 가는 연결고리가 깨짐 그래서 안닫힘

 

수정해야함

//팝업창 닫기
function CloseWindow(){
	if(window.opener) window.opener.location.reload(true);
	window.close();
}

 


삭제

@RequestMapping(value="/remove", method=RequestMethod.GET)
	public String remove(String id, HttpSession session, Model model) throws SQLException{

리무브석세스에게 줄 파라미터가잇다면 모델에 심으려고 모델받은거임

 

리턴타입 스트링이다.

수정했던것처럼 리터럴스트링안주고

포워드해서

리무브석세션이라는 jsp에서 스크립트내보내는방식으로 해보자

 

시나리오:

아이디받아서 리무브하기전에 일단 확인해야함 (지우기전에!) 로그인한 유저인지!

 

일단 지우고 세션 날릴거임

그러기위해서는 이녀석의 사진정보 (디비에잇음) 을 지워야하는데 받은건 아이디밖에없음

그럼 디비날리기전에 정보가져온다음 킵하고 그다음 지워야함 안그러면 사진정보에대한 데이터를 알수가없다.

 

//이미지 파일을 삭제 (겟 멤버 먼저하고)
		member = memberService.getMember(id);
		
		//삭제
		String savePath = this.picturePath;
		File imageFile = new File(savePath, member.getPicture());
		if(imageFile.exists()) {
			imageFile.delete();
		}

 

 

이제 이미지는 지웟고

디비내용 삭제하고

//디비지우기
		memberService.remove(id);

세션로그아웃시키면됨

//삭제되는 회원이 로그인중인 회원인경우 로그아웃
		MemberVO loginUser = (MemberVO) session.getAttribute("loginUser");
		if(loginUser.getId().equals(member.getId())) {
			session.invalidate();
		}
		
		model.addAttribute("member",member);
@RequestMapping(value="/remove", method=RequestMethod.GET)
	public String remove(String id, HttpSession session, Model model) throws SQLException{
		String url = "member/removeSuccess";
		//리무브석세스에게 줄 파라미터가잇다면 모델에 심으려고 모델받은거임
		MemberVO member;
		
		//이미지 파일을 삭제 (겟 멤버 먼저하고)
		member = memberService.getMember(id);
		
		//삭제
		String savePath = this.picturePath;
		File imageFile = new File(savePath, member.getPicture());
		if(imageFile.exists()) {
			imageFile.delete();
		}
		
		//디비지우기
		memberService.remove(id);
		
		//삭제되는 회원이 로그인중인 회원인경우 로그아웃
		MemberVO loginUser = (MemberVO) session.getAttribute("loginUser");
		if(loginUser.getId().equals(member.getId())) {
			session.invalidate();
		}
		
		model.addAttribute("member",member);
			
		return url;
	}

jsp 만들어야댐

이경로

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="UTF-8"%>

 
<script>
alert("아이디${member.id}님을 삭제했습니다.");
window.opener.location.reload(true);
window.close();
</script>

 

테스트로 로그인하고 삭제햇는데 좌측 그대로임 (로그인화면으로 가지는 않음 로그인체크필터 꺼져잇어서)

 

이거 해주기

 


AOP : 관점지향적 프로그램

 

목적 : 트랜젝션이 안됨 지금

그말은 즉 디비가 따로따로 움직이고잇다는 말임

 

객체지향이아니라 관점지향으로 프로그래밍하겟다는말임

부품화의 개념이 아니라 관점에 의한

 

양치질 : 칫솔에 치약을 뭍혀서 이를 구석구석 닦는 행위

양치질이 뭐에 종속적이진않음

 

식사 랑 양치질이 관련은 없는데

이 두개를 흐름을 연관을 짓는.. + 하면 관점이 생김

> 식사 한 후 양치질 이 생김

 

인증은 인증대로 방법이잇는거임 (공인인증서, 지문, 휴대폰...) 근데 이체를 붙이면 관점이 만들어짐

인증 후 이체

 

ㅇㅇ할때 ㅇㅇ 한후 ㅇㅇ 하기

 

기능에대해서는 독립적으로 생각하는데, 거기에 다른걸 붙이면 뭐가 먼저인지. 그게됨

프로그래밍을 하다보면 독립적기능들이 붙게되면 전후관계가 생긴다는말

전후관계 > 이게 수평적관점임 Aspect

그니까, 원래는 관련이없엇던 애들인데 연관이 지어지면 순서가 생긴다. 수직구도가 아닌 수평적관점임

 

양치 식사 추ㅣ침 데이트 중에서 양치는 따로뺴서 전이나 후에 걸고싶은거임

우리가전에햇던 부품화는 아님 부품화는 "반드시 필요, 코드에 포함,그게없으면 안되는거"임 그걸하기위해선 얘가 반드시 잇어야하는. has의 개념

관점지향은 없어도 되는.. 못하는건아닌데 잇으면 좋은

근데 이것들이 여기저기 전후관계로 산재하기떄문에 그때마다 일일히 구현할건가?? 하는거임

 

인증 이체 조회 개설 펀드 잔액조회 등등

이중에 인증이 필요한곳에 넣어주기

그 전후로 이체조회개설펀드등이 실행되는거임

 

우리가 지금까지 햇던 셋메서드도 유연하지만 셋메서드가 잇어야하기떄문에 넣은거고 없이는 안되는거임

근데 수평적관점은 없어도 기능이됨 근데 걸면 건 상태로 진행하는것

 

어던 프로세스를 쭉 만들고, 그런 모듈적인 것 (없어도되는데 잇으믄 좋은)이 발생하면,

스탑워치로 시작전에 시작, 끝나구 끝나는버튼 누르는것같은거 .. 이놈을 aspect라고 함

 

식사데이트취침등을 다따로만들고 양치질을 aspect로 만듦

양치질이 없으면 되긴하지만 드러움

 

식사데이트취침 중간중간에 껴줄거임 근데 코드를 바꾸는건 아님

 

이걸만든이유 : 코딩을 하다보면 어디서 저기서 요기서 필요해서 주게되다보니까 반복이됨. 근디 또 매번필요한게 아니라 필요할때만 적절하게 넣어주기위해서 ..

꼭 가지고잇어야하는거 아님. 셋메서드도 아님. 그냥 걔를 걸어주면 진행이된다.

 

하루일과중 분명 양치가필요한곳이 잇음 그렇다고 소스코드를 고치는게 아니고

양치를 건다. 그럼 양치가 이 프로세스에 간섭을 해서 전후로 실행을 하게된다.

 


Aspect(수평적관점)

AOP : Aspect Orientes programming

 

~하기 전/후로 ~~한다. > 이런건 다 수평적관점임

이게 반복적으로 이루어진다는점에 주목

 

얘네들은 독립적인데 (다양)
이건 하나인거임

이걸 목적으로 한 프로그래밍을 AOP라고 한다

AOP랑 aspect는 다름 aspect는 말그대로 이런 관계를 얘기하는거고 그런 관곌 프로그래밍한게 AOP

 

객체지향 (Object oriented) 는 부품화하면서 재활용하는게 목적임

근디 한계가잇는게, 상속을 시키건 has a 를 시키건 간에 그걸 안하면 전혀관계가 없게됨.

연관을 지어서실행할수가없기떄무네 계속 중복해서 호출해야함

 

근데 관점지향은 그렇지않음.

 

기존의 방식은 has a 나 extends의 방식으로 되어잇음

근데 Spring 와서 이걸 아주 편하게 만들수잇게 되어잇음?

 

이것들을 용어로 각각 구분해서 만들어놧고 각각 우리가 주면 됨

 

용어정리:

기준!

 

연결한다. 시점
충고

aspect는 크게 세가지

꼭 기억!!!~!

포인트컷은 다양하나 어드바이스는 반복됨. 그게반복되는게 문제가되니까 하나로 빼서 걸어준다(조인포인트가)

 

스프링에는 AOP 모듈이 잇는데 aspect가 없음 -> 프록시를 건드려야함

 

* 프록시

 

프록시 참고:

velog.io/@max9106/Spring-%ED%94%84%EB%A1%9D%EC%8B%9C-AOP-xwk5zy57ee

 

[Spring] 프록시 패턴 & 스프링 AOP

스프링 AOP는 프록시 기반의 AOP 구현체이며, 스프링 Bean에만 AOP 적용 가능하다. 프록시 패턴이란? 프록시 객체는 원래 객체를 감싸고 있는 객체이다. 원래 객체와 타입은 동일하다. 프록시 객체가

velog.io

전선은 구리선만 잇어도 전기흐르는데 왜 비닐씌워놓음? 그거안씌우면 전기안가는건 아니지만 안갈수도잇게됨

그 피복씌운 그 영역을 자바에서 프록시라고 생각하면됨

구리 + 피복 = 전선 (실행)?

 

또는 경기를 할떄 경기를 지켜보는 아나운서, 수행요원들, 카메라, 관중석들이 포진되어잇음 경기장엔 운동선수들이 경기만 하는데 그 운동을 위해서는 조명도, 음ㅇ향시설도 여러가지가 수반됨

그 영역을 프록시라고 함.

 

우리가 실행하는 프로그램만 실행하는듯하지만 안보이는 제반적 요소들이 다 있다는거임

 

에스페트를 걸어주려면 그 영역을 써야함

 

JVM이 실행할떄 뭔가 메서드먼저 준비해두는것도 프록시, 콜스택(쌓는.. 이게프록시.. 이거끝나고 이거가고 이거가고하는거 챙겨두는곳.. 메서드끝나고 가야하는거 감시하는영역이 프록시)/메서드에어리아/...

익셉션터지면 에러메세지 나오는것도 감시하는 프록시가 있기떄문에 가능한거임

 

*

인스턴스만들면 힙메모리에 잡히는건 안다 

그럼 인터페이스는?? 인스턴스못만드는데 어디에잇길래 알수잇음??

바로 프록시임!~!

그래서 인터페이스를 만들면 인스턴슷생성못하기떄문에 힙이아닌 프록시에 상주하고잇게됨

그렇기떄문에 우리가 impl햇을때 나오는거임

 

감시할때 프록시에 있는 인터페이스를 이용함!

 

 

인터페이스 이용해서 잡으면 실행도전에 잡을수잇다?

 

에스펙트는 관점지향.. (서로 독립적인 애들이 조인포인틍에서 엮어지느거임)

양치를 안햇다고 밥을 못먹는건아님

 

우리가 실행하는곳은 타겟영역이지만

우리가 에스펙츠를 구현하는곳은 프록시

프록시를 이용해서 타겟에 뭐가 실행되고잇는지를 감시하는거임

 

에스펙트는 관점 포인트컷은 대상 조인포인트는 접점 ... 잘알고잇기

 

*어드바이스부분이 반복적이지않는것은 에스펙츠로 만들지않음 걍 메서드로 코드분리하든지... 객체지향으로 만들고말지

 

전후관계가 잇는데 반복된다 ? aspects

 

우리는 어따써먹음? 트랜젝션!!!

 

서비스마다 반복적으로 생김

그걸 관점지향으로 할거임~!

 

서비스실행할떄마다 보고잇다가 서비스 실행하면 잡아다가 보는거임

익셉션(기준) 터지면 롤백! 이런식으로 안터지면 커밋!

서비스메서드 전후로 트랜젝션 해야함

서비스는 각각다름~

 

스프링이 AOP는 잇는데 aspects 는 없음

총은 잇는데 총알이없는격

 

에스펙츠장착위해

AOP 디펜던시넣고

 

자바로 구현하는건 비추
어드바이스 종류가 아니라 조인포인트 종류임

 

AOP라는 프로젝트를 만들어서 적용해보고 넘어오겟음

 

Spring_AOP

 

pom.xml

 

자바도 1.8로***등록전에 파라미터에 관한 이슈

 

이미잇음

maven aspectjweaver

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
		<dependency>
		    <groupId>org.aspectj</groupId>
		    <artifactId>aspectjweaver</artifactId>
		    <version>${org.aspectjweaver-version}</version>
		</dependency>
		

 

 

이놈 프록시에 올라감

package com.spring.aop.pointcut;

public interface Behavior {

	void 잠자기();
	void 공부하기();
	void 밥먹기();
	void 데이트();
	void 운동();
	void 놀기();
	void 정신수양();
	
}

이거에대한 클래스임플만들자

 

package com.spring.aop.pointcut;

public class BehaviorImpl implements Behavior {

	@Override
	public void 잠자기() {
		System.out.println("쿨쿨 잠을 잡니다.");
	}

	@Override
	public void 공부하기() {
		System.out.println("열심히 공부를 합니다.");

	}

	@Override
	public void 밥먹기() {
		System.out.println("밥을 먹어요");

	}

	@Override
	public void 데이트() {
		System.out.println("데이트에 갑니다.");

	}

	@Override
	public void 운동() {
		System.out.println("달리기를 합시다");

	}

	@Override
	public void 놀기() {
		System.out.println("열심히 놉니다.");

	}

	@Override
	public void 정신수양() {
		System.out.println("정신수양을 합니다.");

	}

}

 

메인메서드

package com.spring.aop.main;

import com.spring.aop.pointcut.Behavior;
import com.spring.aop.pointcut.BehaviorImpl;

public class 하루일과 {

	public static void main(String[] args) {
		//일단 행동을 가져옴
		Behavior behavior = new BehaviorImpl();
		
		//하루일과는 이렇다
		behavior.밥먹기();
		behavior.정신수양();
		behavior.밥먹기();
		behavior.공부하기();
		behavior.놀기();
		behavior.데이트();
		behavior.운동();
		behavior.밥먹기();
		behavior.잠자기();
		
	}

}

이렇게 사니까 이가썩는다

 

양치질을 안해서

 

그래서뭔가먹은다음이나 자기전에 양치를 해야한다

 

양치를 할라다보니까 소스 뜯어고쳐야할판임

근데그렇게하기싫음

 

반복적인 일을 클래스나 메서드에 다 타이핑하기싫은거임

 

모든사람이 다 양치를 하는것도아니고 한두번빼먹는다고 안되는것도아님

그래서 결합도높게 매서드안에 양치를 넣고싶지는 않은거임

 

그럼 일단 빈등록을 해야겟음 new 안쓰려고....

 

결합도가 낮게 해보자