Spring 배우기
spring 시작전 환경 설정 법 참고 : https://boxfoxs.tistory.com/334
https://iwbtbitj.tistory.com/91 <- 이것도 환경 설정 참고
이클립스에서 help->elipseMarketplace 들어가서 spring 다운
해당패키지 에서 -> 오른쪽 버튼 -> new -> other
DI 이란 ? Dependency injection
객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입을 시켜주는 방식
어떠한 작업에대한 기능을 수행하기 위해서 다른객체가 필요할때 그 객체를 주입시켜 이용하는 것.
<spring xml로 사용한 이유>
b라는 인터페이스를 구현한 b2의 객체가 있고
b라는 인터페이스를 사용하고 있는 s 라는 객체가 있을경우
결합 상태를 바꾸기 위한 코드가 수정될수 있기 때문에 소스코드 수정 없이 결합상태를 바꿀수 있게 하기 위해서 사용
/ Exam exam = new NewlecExam();//// ExamConsole console = new INlineNewlecExam(exam);// ExamConsole console = new GridExamConsole(exam);//// console.setExam(exam);
NewlecExam 이라는 클래스는 exam 이라는 인터페이스를 상속 받고 있고ExamConsole 이라는 print라는 추상메소드를 가지고 있는 인터페이스를 INlineNewlecExam,GridExamConsole 라는 두 클래스가 상속 받고 있다고 할때 , 각 클래스 에 exam 이라는 객체를 결합 시키는 과정에서 코드를 변경해주는것이 번거롭다.
하지만 spring에서는 DI에 특화 되어 있어 현재 공부에서는 XML 파일 안에서이름만 변경하여 쉽게 DI를 할수 있다.
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"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"><!-- Exam exam = new NewlecExam(); --><!-- 생성할 객체 이름 클래스 이름 패키지 까지 꼭 써주기 --><bean id="exam" class="spring.di.entity.NewlecExam"></bean><!-- ExamConsole console = new GridExamConsole(); --><bean id="console" class="spring.di.ui.INlineNewlecExam"><!-- setting 하는 법 console.setExam(exam); --><!--console이 갖는건데 name은 setExam 인데 규칙상 set생략 앞에 대문자 소문자로 그리고 ref는 referance exam를 넣는다.--><property name="exam" ref="exam"></property></bean></beans>
xml 지시서를 활용하여 main에서 사용
// 지시서 읽기
ApplicationContext context = new ClassPathXmlApplicationContext("spring/di/setting.xml");// xml에서 id 값 가져와서 사용해보기//ExamConsole console =(ExamConsole) context.getBean("console") ;ExamConsole console =context.getBean(ExamConsole.class) ;console.print();
Array list를 spring에서 활용하기
List<Exam> exams = new ArrayList<>();
exams.add(new NewlecExam(1,1,1,1));
for(Exam e : exams){System.out.println(e);}
위의 내용을 spring에서 지시해보시 setting.xml에서
<bean id="exams" class="java.util.ArrayList"></bean>
/*-> 위 코드와 같이 java.util.ArrayList라는 클래스를 exams라는 이름으로 만들어준다 . List<Exam> exams = new ArrayList<>();*///-> <bean>안에 collection 형태로 값을 넣어주는데
<constructor-arg>
<!-- exams.add(new NewlecExam(1,1,1,1)); -->
<list>
<bean class="spring.di.entity.NewlecExam" p:kor="1" p:eng="10"></bean>
<ref bean="exam"/>
</list>
</constructor-arg>
//이러면 list라는 collection 객체가 만들어지고 그 안에 직접 bean을 만들어 생성하거나 ref 를 이용하여 만들어진 객체를 불러올수 있다. (현재 2개 불러옴 )
xml에서 조차도 열어서 변경하는게 번거로우니 자바 안에서 설정만 변경하는 방식 인 어노테이션 기법이 만들어졌다.
어노테이션
-1.@Autowired 를 통해서 DI 결합
<bean id="console" class="spring.di.ui.INlineNewlecExam"><property name="exam" ref="exam"></property>-->
</bean>
INlineNewlecExam 안 있는 setname을 이용하여 객체를 만들었지만
<property>를 생략하고
xml 에서 객체를 선언하지 않고 java 안에서 객체를 만들고 사용하는 방법
program.java
ApplicationContext context = new ClassPathXmlApplicationContext("spring/di/setting.xml");// xml에서 id 값 가져와서 사용해보기ExamConsole console =(ExamConsole) context.getBean("console") ;
setting.xml
<context:component-scan base-package="spring.di.ui"></context:component-scan>
INlineNewlecExam.java
@Component("console")public class INlineNewlecExam implements ExamConsole {@Autowired(required = false)@Qualifier("exam2")private Exam exam;public INlineNewlecExam() {}
- > setting.xml 에서는 아무런 코드 작성 없이 어노테이션 기법으로 객체를 만들고 결합까지 가능
또한, 객체에 대한 기본값 설정 또한 어노테이션으로 가능하다.
(단, <context:component-scan base-package=”spring.di.ui,spring.di.entity”></context:component-scan>을 setting.xml에 추가해야함 해당 패키지 경로가 달라 경로 두개를 지정 해서 component를 찾으라고 지시해야함)
@Componentpublic class NewlecExam implements Exam {@Value("20")private int kor;@Value("30")private int eng;private int math;private int com;
...}
사실 @Component 는 @Controller @Service @Repository 세개로 구분해서 용도에 맞게 사용해야 한다.
xml을 사용하지 않고 xml의 내용을 java로 만들어 사용
/*<context:component-scan base-package="spring.di.ui,spring.di.entity">* </context:component-scan><!-- <bean id="exam" class="spring.di.entity.NewlecExam">*/@ComponentScan("spring.di.ui") // @ComponentScan({"spring.di.ui","spring.di.entity"})@Configurationpublic class NewlecDIConfig {@Beanpublic Exam exam() { // bean에서 id 값과 메도스 값 동일하게return new NewlecExam();}}
위에 NewlecDIConfig.class 를 적용 시켜 program.class 에서 사용
/* XML 지시서 읽기ApplicationContext context =new ClassPathXmlApplicationContext(“spring/di/setting.xml”);*/ApplicationContext context = new AnnotationConfigApplicationContext(NewlecDIConfig.class);
ApplicationContext context = new AnnotationConfigApplicationContext(NewlecDIConfig.class);
AOP 이해해보기
AOP란? 기능을 핵심 비지니스 로직과 모듈로 구분하고 핵심 로직에 영향을 주지 않고 사이사이에서 공통으로 모듈을 효과적으로 잘 끼워 넣도록 하는 개발 방법
-개발자 입장에서 사용자에게 제공하는 코드 외 걸리는 시간이나 업무적으로 필요해서 잠깐 잠깐 확인해보기 위해서 만들어 놓은 코드들을 따로 분리
자바를 통해서 확인 proxy 사용
프록시란>?
프록시는 ‘대신’ 이라는 의미를 가지고 있으며, 프로토콜에 있어서 대리 응답 등에 사용하는 개념
보안상의 문제로 직접 통신을 주고 받을수 없는 것과 같은 상황에 그 사이에서 프록시를 이용하여 중계를 하는 개념이라고
볼 수 있습니다.
Exam 이라는 interface를 상속 받고 있는 NewlecExam 에서 total 과 avg 업무를 수행하고 있을때, 개발자 입장에서 해당 되는 시간을 알아보고 싶을때 따로 aop 를 활용하여 코드 작성
NewlecExam. java
public int total() {// 개발자 관점의 AOP 에서 현재 걸리는 시간을 알아보고 싶을떄 앞 뒤에 뭔가를 작성 그것을 AOP 로 따로 구현// long start = System.currentTimeMillis();// 개발자 관점에서 현재 사용되고 있는 코드에 뭔가를 확인하려고 코드를 작성할때 aop를 통해서 따로 관리 그것을 spring으로 하면 더 쉽게 해줌int result =kor+eng+math+com;try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}//// long end = System.currentTimeMillis();//// String message = (end -start)+"걸렸습니다";// System.out.println(message);return result;}@Overridepublic float avg() {float result =total()/4.0f;return result;}
-> 위에서 일부러 thread.sleep으로 시간을 좀 주워 걸리는 시간 확인
개발자가 확인하고 싶을때
public static void main(String[] args) {Exam exam = new NewlecExam(1,1,1,1);Exam proxy = (Exam)Proxy.newProxyInstance(NewlecExam.class.getClassLoader(), new Class[] {Exam.class},new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {long start = System.currentTimeMillis();//여기서 지점을 잡아준다.Object result = method.invoke(exam, args);long end = System.currentTimeMillis();String message = (end -start)+"걸렸습니다";System.out.println(message);return result;}});// new class[] {Exam.class} 라는 인터페이스 인데 앞에 NewlecExam 외 여러개 인터페이스에 대한 정보를 활용System.out.println("total"+proxy.total());System.out.println("total"+proxy.avg());}
- > 따로 확인하여 업무에 있는 주석 코드를 따로 해주지않아도 걸리는 시간을 구할수 있었다 .
proxy는 가짜라고 생각하고 Proxy.newProxyInstance(loader, interfaces,h);
-loader 실제 업무 이 예제에서는 NewlecExam
-interfaces 는 사용하는 인터페이스이지만 복수 이니 new Class[] {Exam.class} 이렇게 사용
-h 에서는 실제로 handler를 만들어서 invoke를 오버로딩 해서 사용 하고 invoke의 매개변수 method를 활용하여 중간에 업무 로직으로 다녀오게 함. method.invoke(exam, 그리고 args에는 해당되는 추상메소드가 들어가 있다 그래서 args를 넣어주면됨)
위에서 했던 내용들을 spring이 더 쉽게 해준다.
걸린 시간을 알아보기 위해서 결합하고 proxy invoke 과정에서 더 쉽게 활용할수 있다 .
beforeAdvice 방식 적용해보기
xml에서는
<bean id=”logBeforeAdvice” class=”spring.aop.advice.logBeforeAdvice”></bean> 으로 객체를 만들어주고
위에서 만들었던 proxy안에 핸들러 안에다가 value 값만 바꿔주면 before로 적용되어 실행된다. <value>logBeforeAdvice</value> <! — 위에 객체를 결합 -> value값을 두개 지정하여 두개 모두 적용 가능 (여러개 가능 )
<bean id="proxy" class=" org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="target"></property><!-- (settarget(), target ref )넣기 --><property name="interceptorNames"><!-- 해들러를 넣어줄떄는 interceptorNames로 넣는다 --><list> <!-- names라는 이름에서 알수 있듯이 열러개가 올수 있으니 list로 값을 지정 --><value>logBeforeAdvice</value> <!-- 위에 객체를 결합 --><value>logAroundAdvice</value><!--around, before 와 같은 aop 방식으로 만들어 놓은 것중 선택하여 넣어서 결합 --></list></property></bean>
after returning / ThrowingAdvice
-> xml은 다른 aop 방식과 동일하게 핸들러 생성하고 property 값 넣어주면됨
public class logAfterReturningAdvice implements AfterReturningAdvice{@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable{System.out.println("returnValue : "+ returnValue + " Method : " + method.getName());}}
public class logAfterThrowingAdvice implements ThrowsAdvice{public void afterThrowing(IllegalArgumentException e) throws Throwable{System.out.println(e.getMessage());}}
스프링 비지니스 로직으로 이해해보기 DI / ojdbc /
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>...<context:component-scan base-package="com.springbook.biz">
</beans>
BoardVO : 데이터를 객체로 만들기 DTO와 비슷한 개념
package com.springbook.biz.board;import java.sql.Date;public class BoardVO {private int seq;private String title;private String writer;private String content;private Date regDate;private int cnt;public int getSeq() {return seq;}public void setSeq(int seq) {this.seq = seq;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getWriter() {return writer;}public void setWriter(String writer) {this.writer = writer;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public Date getRegDate() {return regDate;}public void setRegDate(Date regDate) {this.regDate = regDate;}public int getCnt() {return cnt;}public void setCnt(int cnt) {this.cnt = cnt;}@Overridepublic String toString() {return "BoardVO [SEQ=" +seq +", title=" +title + ", writer=" +writer + ",content="+content +",regDate=" + regDate+ ", cnt=" +cnt+ "]";}}
BoardDAO : 데이터 연결 및 함수 사용
나중에 BoardService라는 이름의 객체가 BoardDAO를 결합해야해서 어노테이션으로 boardDAO 객체 생성
package com.springbook.biz.board.impl;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;import org.springframework.stereotype.Repository;import com.springbook.biz.board.BoardVO;
import com.springbook.biz.com.JDBCUtil;@Repository("boardDAO") // component와 똑같은 느낌 : boardDAO 라는 이름의 객체를 생성하겠다 .
public class BoardDAO {private Connection conn =null;
private PreparedStatement stmt =null;
private ResultSet rs =null;
//sql 명령어 만들어 놓기 nvl 은 nvl(arg1,arg2) -> arg1 값이 null 이면 arg2 으로 바꿔준다.
private final String sql="insert into board(seq,title,writer,content) values("
+ "(select nvl(max(seq),0)+1 from board),?,?,?)";
//
public void insertBoard(BoardVO vo)
{
System.out.println("jdbc로 insert 하기");
try {
conn = JDBCUtil.getConnection();
System.out.println("연결 성공 ");
stmt = conn.prepareStatement(sql);
stmt.setString(1,vo.getTitle());
stmt.setString(2,vo.getWriter());
stmt.setString(3,vo.getContent());stmt.executeUpdate();
} catch (Exception e) {
System.out.println(e);
} finally
{
JDBCUtil.close(stmt, conn);
}
}
}
JDBCUtil : conn stmt 등 close를 매번 하기 때문에 따로 클래스로 지정
package com.springbook.biz.com;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;public class JDBCUtil {
public static Connection getConnection() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url ="jdbc:oracle:thin:@localhost:1521:orcl";
String user="test";
String password ="test";
System.out.println("연결 성공 ");
return DriverManager.getConnection(url,user,password);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void close(PreparedStatement stmt, Connection conn)
{
if(stmt!=null)
{
try {
if(!stmt.isClosed()) stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
stmt= null;
}
}
if(conn!=null)
{
try {
if(!conn.isClosed()) conn.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
conn= null;
}
}
}
public static void close(ResultSet rs, PreparedStatement stmt, Connection conn)
{
if(rs!=null)
{
try {
if(!rs.isClosed()) rs.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
rs= null;
}
}
if(stmt!=null)
{
try {
if(!stmt.isClosed()) stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
stmt= null;
}
}
if(conn!=null)
{
try {
if(!conn.isClosed()) conn.close();
} catch (Exception e) {
e.printStackTrace();
}
finally {
conn= null;
}
}
}
}
BoardServiceImpl
boardService라는 이름으로 객체 어노테이션
package com.springbook.biz.board.impl;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.springbook.biz.board.BoardService;
import com.springbook.biz.board.BoardVO;@Service("boardService") // boardService라는 객체를 만드는데 BoardDAO를 주입시켜 만든다.
public class BoardServiceImpl implements BoardService {
@Autowired
private BoardDAO boardDAO;
public void insertBoard(BoardVO vo)
{
boardDAO.insertBoard(vo);
}}
BoardService 라는 인터페이스 여러 클래스들이 인터페이스를 상속받는다.
package com.springbook.biz.board;public interface BoardService {void insertBoard(BoardVO vo);}
Main : xml과 연결하고 객체 이름을 getbean 하여 insert 해보기
package com.springbook.biz.board;import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;public class BoardServiceClient {
public static void main(String[] args) {
AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
BoardService boardService =(BoardService) container.getBean("boardService");
//BoardService boardService = new BoardServiceImpI(BoardDAO);
//BoardServiceImpl 라는객체가 boardService로 생성되어 있으니 그것을 실행.
BoardVO vo = new BoardVO();
vo.setTitle("임시 제목");
vo.setWriter("홍길동");
vo.setContent("임시 내용 ...");
boardService.insertBoard(vo);
}}
SPRING 비지니스로직 DI
- oracle CRUD 구현을 통해서 SPRING DI 결합을 XML 및 어노테이션 기법 익히기
UserDAO에서는 id와 password를 비교하여 insert함수를 사용하는 함수 구현
어노테이션으로해보기
만들어 놓은 XML 에서 (application.xml 에서) namespace context 추가 하기
프로젝트 src/main/resources 안에 new -> project -> other
그후, <context:component-scan base-package=”com.springbook.biz”></context:component-scan>를 xml에 써주면 어노테이션을 해당 패키지에 적어 놓았다는 의미가 된다.
그후, UserDAO를 Autowired로 결합 시켰으니 UserDAO도 어노테이션으로 객체를 만들어 줘야 한다.
나머지는 XML방식과 동일하게 사용되고 결과값은 XML과 같다.
Spring MVC 패턴 이해하기
Spring MVC 하기 전 MODEL1 2 실습후, SPRING 프레임워크와 비슷한 Controller 및 DispatcherServlet 직접 구현해보기
DispatcherSerlvet.java : 모든 Controller가 들어있는 handlerMapping 값을 init()에서 사용 / viewResult 를 이용하여 url 값을 적용
package com.springbook.view.controller;import java.io.IOException;
import java.util.List;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;import com.springbook.biz.board.BoardVO;
import com.springbook.biz.board.impl.BoardDAO;
import com.springbook.biz.user.UserVO;
import com.springbook.biz.user.impl.UserDAO;public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private HandlerMapping handlerMapping;
private ViewResolver viewResolver;
@Override
public void init() throws ServletException {
handlerMapping = new HandlerMapping();
viewResolver = new ViewResolver();
viewResolver.setPrefix("./");
viewResolver.setSuffix(".jsp");}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
process(request, response);
}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
process(request, response);
}
private void process(HttpServletRequest request, HttpServletResponse response) throws IOException
{
String uri = request.getRequestURI();
String path = uri.substring(uri.lastIndexOf("/"));
Controller ctrl = handlerMapping.getController(path);
String viewName = ctrl.handleRequest(request, response);
String view =null;
if(!viewName.contains(".do"))
{
view = viewResolver.getView(viewName);
}
else
{
view = viewName;
}
response.sendRedirect(view);
}}
HandlerMapping.java : 모든 Controller 구현한 것들을 집어 넣고
getController를 통해서 url에 해당되는Controller를 반환해준다.
package com.springbook.view.controller;import java.util.HashMap;
import java.util.Map;public class HandlerMapping {
private Map<String,Controller> mappings;
public HandlerMapping() {
mappings = new HashMap<String, Controller>();
mappings.put("/login.do", new LoginController());
mappings.put("/getBoardList.do", new GetBoardListController());
mappings.put("/getBoard.do", new GetBoardController());
mappings.put("/insertBoard.do", new InsertBoardController());
mappings.put("/updateBoard.do", new UpdateBoardController());
mappings.put("/deleteBoard.do", new DeleteBoardController());
mappings.put("/logout.do", new LogoutController());
}
public Controller getController(String path)
{
return mappings.get(path);
}}
viewResolver : 접미사와 접두사를 받고 해당되는 viewName에 붙여준다.
package com.springbook.view.controller;public class ViewResolver {public String prefix; //접미사public String suffix; // 접두사public void setPrefix(String prefix) {this.prefix = prefix;}public void setSuffix(String suffix) {this.suffix = suffix;}public String getView(String viewName){return prefix + viewName + suffix;}}
Spring MVC framework로 적용하기
web.xml 설정 : springframework에 DispathcerServlet 이용
<!-- spring MVC 패턴을 위한 SPRING DISPATCHERSERVLET 프레임워크사용 action이라는 이름에 맞게 action 뒤에 -servlet.xml 이라는 파일을 찾아서 적용시킨다.--><!-- 하지만 원하는 xml을 적용할 경우 init -param을 잉ㅇ하여 해당되는 xml 적용 가능 --><servlet><servlet-name>action</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/config/presentation-layer.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>action</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping><!-- 한글파일을 항상 적용하기 위한 filter링 처리 --><filter><filter-name>characterEncoding</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter-mapping><filter-name>characterEncoding</filter-name><url-pattern>*.do</url-pattern></filter-mapping>
만든 xml presentation-layer.xml : Controller java 객체를 생성후
springframework에서 제공하는 HandlerMapping에 결합.
<bean id="login" class="com.springbook.view.controller.LoginController"></bean><bean id="getBoardList" class="com.springbook.view.controller.GetBoardListController"></bean><bean id="getBoard" class="com.springbook.view.controller.GetBoardController"></bean><bean id="insertBoard" class="com.springbook.view.controller.InsertBoardController"></bean><bean id="updateBoard" class="com.springbook.view.controller.UpdateBoardController"></bean><bean id="deleteBoard" class="com.springbook.view.controller.DeleteBoardController"></bean><bean id="logout" class="com.springbook.view.controller.LogoutController"></bean><!-- spring framework의 핸들러매핑을 사용하여 해당 키값에 해당하는 bean 객체를 실행 시킨다. --><bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"><property name="mappings"><props><prop key="/login.do">login</prop><prop key="/getBoardList.do">getBoardList</prop><prop key="/getBoard.do">getBoard</prop><prop key="/insertBoard.do">insertBoard</prop><prop key="/updateBoard.do">updateBoard</prop><prop key="/deleteBoard.do">deleteBoard</prop><prop key="/logout.do">logout</prop></props></property></bean>
로그인 Controller (모든 Controller는 ㅡ ModelAndView를 반환 )
public class LoginController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) {String id = request.getParameter("id");String password = request.getParameter("password");UserVO vo = new UserVO(); // USERDTO와 동일vo.setId(id);vo.setPassword(password);UserDAO userDAO = new UserDAO();UserVO user = userDAO.getUser(vo);ModelAndView mav = new ModelAndView();if(user!=null){mav.setViewName("getBoardList.do");}else{mav.setViewName("login.jsp");}return mav;}}
어노테이션으로 적용해보기
context namespaces 추가하고 xml에 어노테이션 적용
<!-- 어노테이션 방식 --><context:component-scan base-package="com.springbook.view.controller"></context:component-scan>
@Controller @RequestMapping ㅇ을 이용하여 로그인 controller 구현
@Controllerpublic class LoginController {// implements Controller@RequestMapping("/login.do")public String login(UserVO vo, UserDAO userDAO, HttpSession session) {//handleRequest(HttpServletRequest request, HttpServletResponse response)UserVO user = userDAO.getUser(vo);if(user!=null){session.setAttribute("userName", user.getName());return "getBoardList.do";}else{return "login.jsp";}}}
화면 구성 보여주는 getBoardController도 마찬가지로 어노테이션 적용
@Controllerpublic class GetBoardController {//implements Controller@RequestMapping("/getBoard.do")public ModelAndView getBoard(BoardVO vo , BoardDAO boardDAO, ModelAndView mav) {//handleRequest(HttpServletRequest request, HttpServletResponse response)mav.addObject("board",boardDAO.getBoard(vo));mav.setViewName("getBoard.jsp");return mav;}}
다른 모든 Controller를 비슷한 방식으로 적용하면 어노테이션으로 사용적용가능 !!