4일차

|
// 1. 스프링 API를 이용한 AOP 기능 실습.

1. AOPTest.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
	<bean id="calcTarget" class="com.spring.ex01.Calculator"/> // 주기능 - 타깃 클래스를 빈으로 지정
	<bean id="logAdivce" class="com.spring.ex01.LoggingAdvice"/> // 공통기능 - 로그기능을 하는 어드바이스를 지정
    //스프링 프레임워크에서 제공하는 ProxyFactoryBean을 이용해 타깃과 어드바이스를 엮어줌.
	<bean id="proxyCal" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="calcTarget"/> // 타깃 빈을 calcTest 빈으로 지정
        // 스프링의 ProxyFactoryBean의 interceptorNames 속성에 logAdvice를 어드바이스 빈으로 설정하여
        // 타깃 클래스의 메소드 호출시 logAdvice를 실행.
		<property name="interceptorNames">
			<list>
				<value>logAdivce</value>
			</list>
		</property>
	</bean>
</beans>

2. Calculator.java

package com.spring.ex01;

public class Calculator {
	public void add(int x, int y) {
		int result= x + y;
		System.out.println("결과: " + result);
	}
	public void subtract(int x, int y) {
		int result= x - y;
		System.out.println("결과: " + result);
	}
	public void multiply(int x, int y) {
		int result= x * y;
		System.out.println("결과: " + result);
	}
	public void divide(int x, int y) {
		int result= x / y;
		System.out.println("결과: " + result);
	}

}


3. LoggingAdvice.java

package com.spring.ex01;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

// 인터페이스 MethodInterceptor를 구현해 어드바이스 클래스를 만듬.
public class LoggingAdvice implements MethodInterceptor{
	
	public Object invoke(MethodInvocation invocation) throws Throwable{
		System.out.println("[메소드 호출 전 : LogginAdivce");
		System.out.println(invocation.getMethod() + "메소드 호출 전");
		
		Object object = invocation.proceed(); // invocation을 이용해 메소드를 호출.
		
		System.out.println("[메소드 호출 후 : LogginAdivce");
		System.out.println(invocation.getMethod() + "메소드 호출 후");
		return object;
	}

}

4. CalcTest.java

package com.spring.ex01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CalcTest {

	public static void main(String[] args) {
    	// AOPTest.xml을 읽어들여 빈을 생성.
		ApplicationContext context = new ClassPathXmlApplicationContext("AOPTest.xml");
		Calculator cal = (Calculator) context.getBean("proxyCal"); // id가 proxyCal인 빈에 접근.
        // proxyFactoryBean은 AOP설정이 반영된 Target객체를 리턴한다.
        // 메소드 호출 전후에 어드바이스 빈이 적용됨.
		cal.add(100, 20);
		System.out.println();
		cal.subtract(100, 20);
		System.out.println();
		cal.multiply(100, 20);
		System.out.println();
		cal.divide(100, 20);

	}

}

// XML 스키마 기반 AOP 퀵 스타트 실습

1. MainQuickStart.java

package spring.apo.ex01;

import org.springframework.context.support.GenericXmlApplicationContext;

import spring.apo.ex01.component.ReadArticleService;

public class MainQuickStart {

 public static void main(String[] args) {
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:acQuickStart.xml");

  ReadArticleService readArticleService = ctx.getBean(ReadArticleService.class);
  readArticleService.read(1); 
  
  ctx.close();
 }
}

2. ProfilerAdvice.java

package spring.apo.ex01.advice;

import org.aspectj.lang.ProceedingJoinPoint;

// Aound Advice
// 다른 advice는 대상객체 호출을 spring FW이 실행
public class ProfilerAdvice {
// ProceedingJoinPoint joinPoint 파라미터이면 -> Around Advice이고,
 public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
  String signatureString = joinPoint.getSignature().toShortString();
  System.out.println(signatureString + " 시작");
  long start = System.currentTimeMillis();
  try {
  // Around Advice이면, proceed() 메소드 제공한다.
   Object result = joinPoint.proceed(); // aspect가 적용될 대상 객체 호출
   return result;
  } finally {
   long finish = System.currentTimeMillis();
   System.out.println(signatureString + " 종료");
   System.out.println(signatureString + " 실행 시간 : " + (finish - start) + "ms");
  }
 }
}

3. asQuickStart.xml

<?xml version="1.0" encoding="UTF-8"?>



<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop"
	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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
       
       
<!-- 공통 기능을 제공할 클래스를 빈으로 등록 -->
 <bean id="profiler" class="spring.apo.ex01.advice.ProfilerAdvice" />

 <!-- Aspect 설정: Advice를 어떤 Pointcut에 적용할 지 설정 -->
 <aop:config>
  <aop:aspect id="traceAspect" ref="profiler">
   // Aspect J의 표현식
   <aop:pointcut id="publicMethod" expression="execution(public * spring.apo.ex01..*(..))" />
   // pointcut 이라는 호출할 메소드의 범위를 결정하고 / * - 모든 파라미터를 가진 / (..) - 하위 패키지까지 포함.
   <aop:around pointcut-ref="publicMethod" method="trace" />
   // around - 호출시점 / trace - 공통기능
  </aop:aspect>
 </aop:config>

 <bean id="readArticleService" class="spring.apo.ex01.component.ReadArticleServiceImpl">
  <property name="articleDao" ref="articleDao" />
 </bean>

 <bean id="articleDao" class="spring.apo.ex01.component.ArticleDaoImpl" />       
       
</beans>

// @Aspect 애노테이션 기반 AOP 퀵 스타트

1. MainQuickStart2.java

package spring.apo.ex02;

import spring.apo.ex02.component.ReadArticleService;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainQuickStart2 {

	public static void main(String[] args) {
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:acQuickStart2.xml");

		  ReadArticleService readArticleService = ctx.getBean(ReadArticleService.class);
		  readArticleService.read(1);

		  ctx.close();
	}
}


2. ProfilingAspect.java

package spring.apo.ex02.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class ProfilingAspect {
	
	@Pointcut("execution(public * spring.apo.ex02..*(..))")
	private void profileTarget() {
		
	}
	
	@Around("profileTarget()") // profileTarget()의 pointcut 정보를 쓰겠다.
	public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
		 String signatureString = joinPoint.getSignature().toShortString();
		  System.out.println(signatureString + " 시작");
		  long start = System.currentTimeMillis();
		  try {
		   Object result = joinPoint.proceed(); // 타겟의 메소드 호출.
		   return result;
		  } finally {
		   long finish = System.currentTimeMillis();
		   System.out.println(signatureString + " 종료");
		   System.out.println(signatureString + " 실행 시간 : " + 
		     (finish - start) + "ms");
		  }	
	}
}

3. asQuickStart2.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:aop="http://www.springframework.org/schema/aop" 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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
       
       <aop:aspectj-autoproxy /> // proxy를 자동으로 호출.

		    <!-- Aspect 클래스를 빈으로 등록 -->
		    <bean id="performanceTraceAspect" class="spring.apo.ex02.aspect.ProfilingAspect" />
		
		 <bean id="readArticleService" class="spring.apo.ex02.component.ReadArticleServiceImpl">
		  <property name="articleDao" ref="articleDao" />
		 </bean>
		
		 <bean id="articleDao" class="spring.apo.ex02.component.ArticleDaoImpl" />

</beans>

@Pointcut 메소드 사용시 입력방법

- 같은 클래스 : 메소드 이름

- 같은 패키지 : 클래스명.메소드이름

- 다른 패키지 : 패지키명.클래스명.메소드이름

// 스프링 애너테이션 이용해 URL 요청 실습

1.action-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:context="http://www.springframework.org/schema/context"
 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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">

 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <!--<property name="prefix" value="/WEB-INF/views/test/" /> -->
  <property name="prefix" value="/WEB-INF/views/test/" />
  <property name="suffix" value=".jsp" />
 </bean>
// 클래스 레벨에 @RequestMapping 처리
 <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
 // 메소드 레벨에 @RequestMapping 처리
 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
 <context:component-scan base-package="com.spring" /> // com.spring 패키지에 존재하는 클래스에 애너테이션 적용되도록 설정.
</beans>

2. main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" 
    isELIgnored="false"  %>
 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<%
  request.setCharacterEncoding("UTF-8");
%>    


<html>
<head>
<meta charset=UTF-8">
<title>결과창</title>
</head>
<body>
<h1>안녕하세요!!</h1>
<h1>${msg} 페이지입니다!!</h1>
</body>
</html>

3. MainController.java

package com.spring.ex01; // 애너테이션이 적용되도록 하려면 해당 클래스가 반드시 Component-scan에서 설정한 패키지나 하위패키지에 존재해야함,

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView; 

@Controller("maincontroller")
@RequestMapping("/test1")
public class MainController {
	@RequestMapping(value="/main1.do", method=RequestMethod.GET)
	public ModelAndView main1(HttpServletRequest request, HttpServletResponse response) throws Exception{
		ModelAndView mav = new ModelAndView(); 
		mav.addObject("msg", "main1");
		mav.setViewName("main");
		return mav;
	}
	@RequestMapping(value="/main2.do", method=RequestMethod.GET)
	public ModelAndView main2(HttpServletRequest request, HttpServletResponse response) throws Exception{
		ModelAndView mav = new ModelAndView();
		mav.addObject("msg", "main2");
		mav.setViewName("main");
		return mav;
	}
	
}

4. web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
 id="WebApp_ID" version="3.0">
 
   <listener>
      <listener-class>
         org.springframework.web.context.ContextLoaderListener
     </listener-class>
   </listener>

   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
      </param-value>
   </context-param>  

 <servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>action</servlet-name>
  <url-pattern>*.do</url-pattern>
 </servlet-mapping>

</web-app>

'Bitcamp > BITCAMP - Spring FW' 카테고리의 다른 글

7일차  (0) 2019.10.15
6일차  (0) 2019.10.11
5일차  (0) 2019.10.10
3일차  (0) 2019.10.07
1일차  (0) 2019.09.30
And