OOP : 객체지향언어
AOP (Aspect-Orient Programming) : 관점 지향 언어
코드의 앞이나 뒤에만 추가가능 중간에는 추가불가능
약간 유령코드느낌 코드보면 없는데 어디서온거지 ? 하면 이거
@After @Before로 앞뒤 코드 추가
@Around도 있는데 실무에서 잘 안씀 기존 코드 망가질 가능성 있음
사수들이 좋아함 자기코드 가만냅두고 AOP로 추가하라함
자기코드 뜯어고치면 새로봐야하니까 내꺼 손대지말라는뜻 ㅠ 흥!
aop 에 또 aop가 붙는거는 막코드
메이븐 aop검색
원래 스타터에있었는데 사라짐 메이븐에서 디펜던시 긁어오기
스프링스타터에서 보이는 스프링부트 버전을 보고 똑같은 버전 다운

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop/3.4.4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>3.4.4</version>
</dependency>
pom.xml에 추가
저거 버전줄 사실 지워도됨 히히
package kr.co.koo;
import java.lang.reflect.Proxy;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class java_aop {
@Before("")
@After("")
public static void main(String[] args) {
Proxy.newProxyInstance(null, null, null);
}
}
//이렇게 다 나오면 잘 된거당
AOP
1. 본코드의 인터페이스 먼저 만들기
2. 인터페이스를 이용한 클래스 만들기 (본코드)
3. aop 클래스 만들기 (본코드를 로드해와서 코드를 추가)
자바의 aop 와 웹의 aop는 문법이 다름
앱개발시에 자바의 aop를 공부하고
지금은 웹의 aop 만 알아두자
로그인 로그아웃할때 그 시간을 테이블을 기록하고싶을때 사용
로그인, 로그아웃 로그를 저장하는 AOP
Oracle 로그 기록 테이블
CREATE TABLE LOG_TABLE(
MID NVARCHAR2(50) NOT NULL,
MTODAY TIMESTAMP DEFAULT SYSDATE NOT NULL
);
기존 컨트롤러
package kr.co.koo.aop;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import jakarta.annotation.Resource;
import kr.co.koo.cdn_service;
@Controller
public class main2_controller {
Logger log = LoggerFactory.getLogger(this.getClass());
//Controller에서 setter값을 입력받은 것들을 AOP getter로 받아서 추가 코드를 작성하게 됨
@Resource(name="user_dto")
user_dto dto;
@GetMapping("/testaop.do")
public String testaop(Model m) {
String mid = "koo";
String mname = "구나영";
this.dto.setMid(mid);
this.dto.setMname(mname);
if(mid.equals("koo")) {
this.log.info("아이디를 확인하였습니다.");
}
m.addAttribute("mname",mname);
return null;
}
@GetMapping("/testaop2.do")
public String testaop2() {
this.log.info("test2가 실행되는 컨트롤러");
return null;
}
@GetMapping("/testaop_logout.do")
public String testaop_logout(Model m, @SessionAttribute(name="userid", required = false) String userid) {
this.log.info("로그아웃 컨트롤러");
this.dto.setMid(userid);
return null;
}
}
aop파일
package kr.co.koo.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import kr.co.koo.cdn_service;
@Aspect //AOP라는 뜻
@Component //해당 클래스는 무조건 실행된다는 뜻
public class main2_aop {
Logger log = LoggerFactory.getLogger(this.getClass());
HttpServletRequest req = null;
HttpSession se = null;
//@Aspect가 달려있어서 리소스를 가져와도 new 가 아니라 해당 메소드가 작동되면서 데이터를 같이 가져오기 때문에 기존거를 가져올 수 있게됨
@Resource(name="user_dto")
user_dto dto;
@Autowired
cdn_service cs;
//@After : 해당 컨트롤러가 작동된 후에 실행되는 AOP
//@Before : 해당 컨트롤러가 작동되기 전에 실행되는 AOP
//execution : 해당 패키지에 잇는 컨트롤러 및 매핑 메소드를 실행하는 명령어
// * : 모든 패키지 중에서
// 뒤에 달린 쟤를 실행시켜
// (..) : 그안의 매개변수까지 다 가져와서 실행시킨다는뜻
// @After("execution(* kr.co.koo.aop.main2_controller.*(..))")
@Before("execution(* kr.co.koo.aop.main2_controller.testaop(..))") //해당 컨트롤러의 모든 메소드에 적용
// public void testaop_a() throws Throwable{ //Throwable : Exception의 엄마 //트라이캐치에 써도됨
public void testaop_a() {
try {
this.log.info("AOP에서 실행되는 로그");
this.req = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();
this.se = this.req.getSession();
// this.log.info(mid); //본코드의 변수 쓸 수 없음 ! 안되는 코드
this.log.info(this.dto.getMid());
this.se.setAttribute("userid", this.dto.getMid());
this.se.setAttribute("useremail", "koona0@naver.com");
int result = this.cs.log_table(this.dto.getMid());
if(result > 0) {
this.log.info("로그인 로그 저장완료");
}
}catch (Throwable t) { //Exception보다 이거를 추천!
t.printStackTrace();
}
}
/* 실무에서는 접속환경, 로그아웃로그인 여부이런거도 들어감 */
//로그아웃되고나서 언제 로그아웃 했는지를 DB에 insert 하도록 코드를 AOP로 작성
@After("execution(* kr.co.koo.aop.main2_controller.testaop_logout(..))")
public void testaop_b() {
try {
this.se.invalidate();
String loid = this.dto.getMid()+"_out";
int result = this.cs.log_table(loid);
if(result > 0) {
this.log.info("로그아웃 로그 저장완료");
}
}catch (Throwable t) {
t.printStackTrace();
}
}
}