Spring

210702_1(Spring)

너굴셉 2021. 7. 2. 18:20

AOP적용하기

--aop를 구현하는 또다른 방법

joinpoint : 모든 결합점 (가능성포함)

pointcut : 적용 결합점 (실제적용지점)

aspect = advisor = pointcut + advice (횡단코드,공통코드)

 

 

UserLoggingPointcut.java

package net.javajigi.advice;

import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.support.StaticMethodMatcherPointcut;

import net.javajigi.user.dao.MySQLUserDAO;
import net.javajigi.user.service.UserServiceImpl;

public class UserLoggingPointcut extends StaticMethodMatcherPointcut{
	public boolean matches(Method method, Class cls) {
		
		/*
		 * if("addUser".equals(method.getName())) { return true; }
		 * 
		 * return false;
		 */
		System.out.println("2222222222222메소드대조");
		return true;
	}
	
	public ClassFilter getClassFilter() {
		return new ClassFilter() {
			public boolean matches(Class cls) {
				System.out.println("1111111111111 클래스대조");
				return(cls==UserServiceImpl.class)||(cls==MySQLUserDAO.class);
			}
		};
	}

}

UserLoggingAdvice.java

package net.javajigi.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class UserLoggingAdvice implements MethodInterceptor {
	
	protected final Log logger = LogFactory.getLog(getClass());
	
	public Object invoke(MethodInvocation invocation)throws Throwable{
		String className = invocation.getThis().getClass().getName();
		
		if(logger.isDebugEnabled()) {
			System.out.println("3333333333333333333메소드실행전");
			logger.debug(className+"."+invocation.getMethod().getName()+"()"+" 시작!!");
		
		Object[] args = invocation.getArguments();
		if((args != null) && (args.length>0)) {
			for(int i = 0; i< args.length; i++ ) {
				logger.debug("Argument["+i+"] :" + args[i]);
			}
		}
		}
		//Tatget 클래스의 메서드를 실행한다.
		Object retVal = invocation.proceed();
		
		if(logger.isDebugEnabled()) {
			logger.debug(className+"."+invocation.getMethod().getName()+"()"+"종료!!");
		}
		System.out.println("44444444444444444 메소드실행후");
		return retVal;
	}


}

applicationContext.xml

	<bean id="userDAOTarget" class="net.javajigi.user.dao.MySQLUserDAO">
		<property name="dataSource">
			<ref local="dataSource"/>
		</property>
	</bean>

<!-- 	<bean id="userDAO" class="net.javajigi.user.dao.MySQLUserDAO">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
	</bean> -->
	<bean id="userDAO" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target">
			<ref local="userDAOTarget"/>
		</property>
		<property name="interceptorNames">
			<list>
				<value>userLoggingadvisor</value><!-- 참조 어드바이저 -->
			</list>
		</property>
	</bean>
	<bean id="userServiceTarget" class="net.javajigi.user.service.UserServiceImpl">
		<property name="userDAO">
			<ref local="userDAO"/>
		</property>
	</bean>


<!-- 	<bean id="userService"
		class="net.javajigi.user.service.UserServiceImpl">
		<property name="userDAO">
			<ref local="userDAO" />
		</property>
	</bean> -->
	<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target">
			<ref local="userServiceTarget"/>
		</property>
		<property name="interceptorNames">
			<list>
				<value>userLoggingadvisor</value><!-- 참조어드바이저 -->
				<!-- 
				<value>emailNotificatinAdvisor</value>
				 -->
			</list>
		</property>
	</bean>
	
	<!-- 어드바이져 설정(advisor = advice + pointcut) -->
	<bean id="userLoggingadvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advisor">
			<ref local="userLoggingAdvisor"/>
		</property>
		<property name="pointcut">
			<bean class="net.javajigi.advice.UserLoggingPointcut"/>
		</property>
	</bean>
	
	<bean id="userLoggingAdvice" class="net.javajigi.advice.UserLoggingAdvice"></bean>

dispatcherServlet --프론트 컨트롤러

클라이언트와 디스패쳐서블릿 매핑 -- Web.xmlHandlerMapping / VierResolver  --스프링xml 매핑Controller -- 액션클래스

 

 

 

 

<load-on-startup>1</load-on-startup> ===>서플릿을 매핑할때 서블릿이 여러개있는경우 우선순위를 결정하는 것

                                                          숫자가 작을수록 우선순위가 높다. 보통 1,2,3 식이나 10,20,30 처럼부여

 

스프링mvc환경파일의 이름을 서블릿명-servlet.xml로 만들면 자동매핑된다

example-servlet.xml ==>스프링mvc환경파일

 

뷰리졸버 

   InternalResourceViewResolver : 특징) 뷰문서가 /WEB-INF/view/xxx.jsp 같은 문서도 해석하고 출력이 가능하다.

 

web.xml

	<!-- DispatServlet의 이름이 "example"인데 이 경우 사용되는
		Spring 설정파일은 WEB-INF/example-servlet.xml이 된다.
	 -->
	 <servlet>
	 	<servlet-name>example</servlet-name>
	 	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	 	<load-on-startup>1</load-on-startup>
	 </servlet>
	 
	 <servlet-mapping>
	 	<servlet-name>example</servlet-name>
	 	<url-pattern>*.do</url-pattern>
	 </servlet-mapping>
	

example-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE 	beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">


<beans>
	<!-- 핸들러 매핑의 정의 -->
	<bean id="beanNameUrlMapping"
		class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />

	<!-- 요청 URL이 http://domainname/hello.do 요청은 HelloController가 처리한다 -->

	<bean name="/hello.do" class="test.spring.mvc.HelloController" />
	<bean name="/simple.do" class="test.spring.mvc.SimpleController" />

	<!-- 뷰 리졸버 InternalResourceViewResolver는 다음과 같이 두개의 프로퍼티를 입력받는다. prefix 
		- controller가 리턴한 뷰 이름 앞에 붙을 접두어 suffix - controller가 리턴한 뷰 이름 뒤에 붙을 확장자 
		예를 들어, HelloController가 처리 결과를 보여줄 뷰의 이름으로 "hello"를 리턴했다고 하자. 이 경우 InternalResourceViewResolver에 
		의해 사용되는 뷰는 "/view/hello.jsp"가된다. 따라서, /view/hello.jsp가 생성한 응답 결과 화면이 클라이언트에 
		전달된다. -->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/view/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>

HelloController.java

package test.spring.mvc;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;

public class HelloController extends AbstractController{
	/* 
	 * AbstractController 클래스의 handleRequest() 메소드는
	 * 내부적으로 필요한 작업을 수행한 뒤, handleRequestInternal()메소드를 호출한다.
	 * 따라서 AbstractController 클래스를 상속받는 경우에는
	 * handleRequest() 메소드가 아닌 handleRequestInternal()메소드를 구현해주어야 한다.
	 */
	
	@Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)throws Exception{
		ModelAndView view = new ModelAndView("hello");
		view.addObject("greeting", "안녕하세요");
		
		return view;
	}

}

SimpleController.java

package test.spring.mvc;

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

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class SimpleController implements Controller {
	
	/* Controller를 구현하는 가장 단순한 방법은 Controller인터페이스를 구현한뒤,
	 * handleRequest()메소드를 알맞게 구현하는 것이다
	 * 아래코드는 구현 예이다.
	 */
	
	public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)throws Exception{
		//request를 사용하여 클라이언트 요청 분석 후
		//클라이언트 요청에 따른 알맞은 처리
		
		ModelAndView mav = new ModelAndView("simple"); //이동할 뷰 이름
		mav.addObject("simplehi", "심플하게 안녕하세요");
		//뷰 페이지에서 ${greering}로 호출하여 사용함
		return mav;
	}

}

hello.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>

<strong>${greeting}</strong>
</body>
</html>

simple.jsp

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>Insert title here</title>
</head>
<body>
<strong>${simplehi}</strong>
</body>
</html>

chapter1에 SpringMVC적용하기

1. 백업해두기~

 

2.web.xml : mvc 서블릿 설정

 

3. 경로매핑계획 

인덱스 로그인 유저리스트 유저모디파이 유저뷰 유저라이트 .do 매핑

xxxx.user --> 패키지.컨트롤러클래스 

 

3-1) userServlet-servlet.xml HM,VR 설정

 

4. Controller클래스 구현

 방법 - xxx_action.jsp 의 내용이 ---> controller로 옮겨가야한다. 

          xxx_action.jsp는 컨트롤이 실행된 결과페이지이다.

 

주의) return mav가 아니라 return null; 하게되면 오류없이 화면이 하얗게 나온다 ㅋ

참조) 스프링 환경문서들 내부의 id로 설정된 인스턴스들은 모든 환경파일에서 공유가된다.

 

했던걸 기억할수있을까... 주말에 수련 ㄱ