2012 년자바카페 OPEN 세미나 주제 : Spring 프레임워크중요구성원리 2012. 6. 16
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
Tier & MVC BROWESER (CLIENT) REQUEST RESPOND FRONT CONTROL FRONT CONTROL V C V JDNI JMAIL MODEL SERVLET REMOTE LOOKUP HOME EJB CREATE REMOTE JDBC JAVAX.SQL..DATASOURCE POOLING JNDI JMS JTA POOL JDOM LDMP DB MOM APP SERVER LDAP MAIL PL V1 SPAGETTI V2 SEPERATION MVC1(JSP CONTROL) MVC2 (SERVLET) MVC2 (SERVLET ACTION) V1 V2 V1 C V2 V1 V2 V1 V2 C C ACTION SERVER BL SERVICE DL DAO DAO DAO DAO EIS Frameset tiles.sitemesh, Freemaker,velocity
Tier/Layer 화면 Tier Layer Client Tier Browser(JS, HTML, CSS) JSP / Serverlet(controller) v1 v2 PL PL View JSP / Serverlet 화면층 V -> V Server Tier BL 로직층 DL (Persistence Layer) 영속성 JDBC/Driver Single tone delegate DAO Model Ibatis(Hivernate) JDBC/Driver 제어, 분기 Controller MVC EIS Tier DB DB MOM
3 Tier Browser Browser User Client Tier Presentation Layer (JSP/Servlet) 요청을동적으로처리하여 HTML 로응답한다. Business Layer (Service, EJB) 요청을받고, 분석, 실행한다. SQL 을이용하여데이터를얻기도하며요청에대한데이터를응답한다. Server Tier Data Layer (Persistence,Integration Layer : DAO, ORM) SQL 을이용하여정보검색, 추가, 수정, 삭제 (CRUD) 를한다. Resource Layer DB EIS Tier
4 Tier Browser Browser User Client Tier Presentation Tier (JSP/Servlet) Web Server HTML 응답 Server Tier Business Tier (Service, EJB) Data Tier(Persistence, Integration Tier: DAO, ORM) Application Server Application Tier CRUD Resource Tier DB EIS Tier
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
Web Server WS = HTTP Server + Web container + Web Engine +Connector
WAS WAS = WS + ES + SERVICE WS=Tomcat ES HTTPD wc = Containner Engin =jasper E.C E.E Service HTTP Server Jsp -> servlet Connector Ibatis (EJB 대신역할수행 ) ActiveDrectory JMDI JMS JTA JMAIL....(40 개정도 ) Data source Pooling LDAP MOM ASF 35/40 40 개넘는서비스중에 35 정도의서비스가구현되어있음.
Life Cycle web.xml 활동준비 / 자원초기화 Container 가메서드호출 init() Servlet init() Request service() service() Servlet destroy() destroy() Request 처리후 Response Response Servlet 자원회수 / 객체소멸
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
MVC 1 request Controller 2 한행의데이터를 DTO 에저장하여사용 4 Model 3 DB 6 response View 5 1 요청 4 6 응답 처리결과에따라해당화면으로 forward 2 데이터를처리하거나얻는다 5 3 CRUD 실행 처리결과에따라해당 Business 객체를넘겨서화면에출력한다
Web History
SoC(Separation of Concern) 종류 workbean usebean Multi Front Action SERVER PL BL SEPERATION MVC1(JSP CONTROL) MVC2(JSP CONTROL) MVC2 (SERVLET) MVC2 (SERVLET ACTION) V1 V2 V1 C V2 V1 V2 V1 V2 V1 C V2 C C ACTION ACTION forward forward forward forward SERVICE DL DAO DAO DAO DAO DAO EIS frameset tiles.sitemesh, Freemaker,velocity
MVC
MVC
Front Servlet
Action Servlet
MVC JSP Centric
MVC Servlet Centric(Action Servlet)
Spagetti
Separation
MVC Model 1 JSP Centric
MVC Model 2 Servlet Centric
Facade
Action
Listener/Filter Listener 특정행위가발생하면등록된메서드를호출 Context 가호출되기직전 ContextListener 의 initializedcontext() 메서드호출 Filter 가로채기
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
Spring 3 대원리 DI / IoC Spring OCP AOP
Bean POJO Bean LifeCycle 없는것 Setter 와 Getter 로구성된것 DTO UseBean LifeCycle 있는것 Servlet(JSP) EJB LCO
Abstraction Programming
<<interface>>imagic +make() : void +print() : void MagicSquareFactory - magicsquarefactory : MagicSquareFactory - MagicSquareFactory + factory(n : int) : Imagic <<create>> + getinstance() : MagicFactory Singletone MagicSquare #n : int #magic : int[] +AMagic(n : int) +make() : void +printmagic() : void +sumrow(row : int) : int +sumdia() : int +sumantidia() : int +ismagic() : boolean +getmagic() : int[] +print() : void factory(n) : Imagic n 값에따라 Odd Four SixMagicSquare 를생성 MagicSquare abstract class : 이탤릭체로표기추상클래스 -MAgicSquare, 추상메서드 -make() make() 메서드내부에서 OddMagicSquare 를생성후 getmagic() 을이용하여 OddMagicSquare 의 int[][] 를얻어온다 OddMagicSquare FourMagicSquare SixMagicSquare XXMagicSquare +make() : void +make() : void +make() : void +make() : void <<use>>
SixMagicSquare private void addmagic( ){ int n=magic.length; OddMagicSquare odd=new OddMagicSquare(n/2); odd.make(); } int [][] mogi=odd.getmagic(); for(int i=0 ; i<n/2;i++){ for(int j=0;j<n/2;j++){ magic[i][j]+=mogi[i][j]; magic[i][j+n/2]+=mogi[i][j]; magic[i+n/2][j]+=mogi[i][j]; magic[i+n/2][j+n/2]+=mogi[i][j]; } }
SixMagicSquare private void addmagic( ){ int n=magic.length; XXMagicSquare odd=new XXMagicSquare(n/2); odd.make(); } int [][] mogi=odd.getmagic(); for(int i=0 ; i<n/2;i++){ for(int j=0;j<n/2;j++){ magic[i][j]+=mogi[i][j]; magic[i][j+n/2]+=mogi[i][j]; magic[i+n/2][j]+=mogi[i][j]; magic[i+n/2][j+n/2]+=mogi[i][j]; } }
SixMagicSquare private void addmagic(imagic odd){ int n=magic.length; odd.make();. Imagic odd; public void setimagic(imagic odd){ this.odd=odd; } private void addmagic( ){ int n=magic.length; odd.make();.
OOP 5 대원리 1. SRP(The Single Responsibility Principle) - 단하나의책임원리 응집도관련 2. OCP(The Open-Closed Principle) - 개방폐쇠의원리 엔터티, 상속 ( 부모변경지양 ) - A---> B (A 를변경하지않고 B 를변경 ) 3. LSP(The Liskov Substitution Principle) - 리스코프교체원리 - 다형성관련 ( 부모로자식을사용 -> 인터페이스사용권장 ) 4. DIP(The Depend Inversion Principle) - 의존의대상을추상클래스나인터페이스권장 5. ISP(The Interface Segregation Principle) - 인퍼페이스격리원칙 - 필요한메서드만갖는인테페이스를구현하라.
OCP OCP StudentController > StudentServiceImple
LSP StudentController > StudentService LSP DIP StudentServiceImple StudentController > StudentServiceImple
ISP TeacherService StudentService PeopleServiceImple ISP
ISP StudentService TeacherService StudentServiceImple TeacherServiceImple
Relation StudentController SqlMapClientTemplate StudentService StudentDao SqlDaoSupport StudentServiceImple StudentDaoImple
Controller public class BoardListController extends AbstractController { private BoardRepService boardrepservice; public void setboardrepservice(boardrepservice boardrepservice) { this.boardrepservice = boardrepservice; } protected ModelAndView handlerequestinternal( HttpServletRequest request, HttpServletResponse response) throws Exception { List<BoardRepDto> list=null; list=boardrepservice.getallboards(); return new ModelAndView("list", "lists", list); } }
Service public class BoardRepServiceImp implements BoardRepService { private BoardRepManager boardrepmanager; public void setboardrepmanager( BoardRepManager boardrepmanager ) { this.boardrepmanager = boardrepmanager; } public int deleteboard(int seq) { return boardrepmanager.deleteboard(seq); } public int deleteboards(int[] seq) { return boardrepmanager.deleteboards(seq); }
Dao public class BoardRepManagerImp extends SqlMapClientDaoSupport implements BoardRepManager { public BoardRepDto getboard(int seq) { BoardRepDto dto=new BoardRepDto(); dto= (BoardRepDto)this.getSqlMapClient(). queryforobject("board.getboard", seq); return dto; }
Wiring <bean id="boardlistcontroller" class="com.board.controller.board.boardlistcontroller" p:boardrepservice-ref="boardrepservice"> </bean> <bean id="boarduserservice" class="com.board.serviceimp.boarduserserviceimp" p:boardusermanager-ref="boardusermanager"> </bean> <bean id="boardrepmanager" class="com.board.daoimp.boardrepmanagerimp" p:sqlmapclient-ref="sqlmapclient" /> <bean id="sqlmapclient" class="org.springframework.orm.ibatis.sqlmapclientfactorybean" p:datasource-ref="datasource" p:configlocation="/web-inf/sqlmap/sqlmapconfig.xml"/>
3.X Controller @Controller public class JHBoardController { @Autowired private IJUserService ijuserservice; @RequestMapping(value = "/registry.do", method = RequestMethod.POST) public String registry(juser dto,model model) { logger.info("welcome JHBoardController registry.do!"+ new Date()); logger.info("welcome JHBoardController "+ dto); ijuserservice.addjuserandroll(dto); return "redirect:/index.do"; }//
3.X Service @Service public class JUserServiceImple implements IJUserService { @Autowired private IJUserDao ijuserdao; @Override @Transactional public void addjuserandroll(juser juser) { ijuserdao.addjuser(juser); ijuserdao.addjrollmap(juser); }
3.x Dao @Repository public class JUserDaoImple implements IJUserDao { @Autowired private SqlMapClientTemplate sqlmapclienttemplate;public SqlMapClientTemplate getsqlmapclienttemplate() { return sqlmapclienttemplate; } @Override public void addjuser(juser dto) throws DataAccessException{ getsqlmapclienttemplate().insert("jusermap.addjuser",dto); } @Override public void addjrollmap(juser dto) throws DataAccessException{ getsqlmapclienttemplate().insert("jusermap.addjrollmap",dto); }
Auto Wiring Config <mvc:annotation-driven /> <context:component-scan base-package="com.hankyung.boards com.hankyung.datemans" />
AOP CC CCC P1 P2 P3 P4 weaving
JDBC Transaction public boolean addjuserandroll(juser juser) { Connection conn=null; boolean iss=false; boolean ist=false; try { conn=getconnection(); conn.setautocommit(false); iss=addjuser(juser,conn); ist=addroll(juser,conn); if(iss&&ist){ conn.commit(); }else{ throw new SQLException(" 등록실패 "); } } catch (SQLException e) { try { conn.rollback(); } catch (SQLException e1) { } }finally{ try { conn.setautocommit(true); } catch (SQLException e) { } this.close(conn, null, null); } return iss&&ist; } public boolean addjuser(juser juser,connection con) throws SQLException{ int count=0; String sql=" INSERT INTO J_USER(ID,NAME,PWD,ADDRESS,PHONE)" + " VALUES(?,?,?,?,?)"; Connection conn=null; PreparedStatement psmt=null; try { conn=con; log("2/6 S addjuser "); psmt=conn.preparestatement(sql); public boolean addroll(juser juser,connection con) throws SQLException{ int count=0; String sql=" INSERT INTO J_ROLLMAP(ROLLMAPID,ID,ROLLID)" + " VALUES(J_ROLLMAP_SEQ.NEXTVAL,?,3)"; Connection conn=null; PreparedStatement psmt=null; try { conn=con; log("2/6 S addroll "); psmt=conn.preparestatement(sql); int i=1; psmt.setstring(i++, juser.getid()); log("3/6 S addroll "); count=psmt.executeup
Transaction 3.x @Override @Transactional public void addjuserandroll(juser juser) { ijuserdao.addjuser(juser); ijuserdao.addjrollmap(juser); } <bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmana ger"> <property name="datasource" ref="datasource"/> </bean> <tx:annotation-driven transaction-manager="transactionmanager"/>
Transaction 2.5 <tx:advice id="transactionadvice" transactionmanager="transactionmanager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="*" propagation="required" rollbackfor="org.springframework.dao.dataaccessexception" /> </tx:attributes> </tx:advice> <aop:config proxy-target-class="true"> <aop:advisor advice-ref="transactionadvice" pointcut="execution(* com.hankyung.boards.model.*service.*(..))" /> </aop:config>
ORM
MyBatis
Spring MVC Web Container 1 Web. XML 3 HendleMapper 에의해 a.do 이면 Custcontroll 을부름 : Mapping 6 딸깍 XML 5 Spring Container Control Controller<interface> 2 Spring Context 리스너하면자동으로읽고들어감 Listener M XML MVC 에자동으로 XML 을이동해줌 이벤트감지 리스터를이용해 XML 을읽음 V,C 4 5 X M L 8 DispacherServlet 딸깍 Titles Resolver JSTL Resolver - sitemash 사용 JSON Resolver View 7 MAV 9 a.do Service Dao 조합 Interface DaoSupport 상속해서 templete 사용 3.0 에서는 @repository 로사용 5 Injection 해줌 Dao XML XML 에등록만해주면 Templet 이준비됨 Model XXXXCustController.java Interface extends Extends 하면자동으로옴 Ver 2.5 Daosuport 강제로올려줌 Templet Ibatis DTO SQL SqlMapConfig.xml CustUser.xml Polling 에서준비된것을사용하는것 리스너종류 Context Session Templet ORM 계열과 Mapping 할수있는 Templet - 환경변수 (xml) 에정의해주면됨 만능커넥터 Sqlmap -ibatis Spring... DataSource Polling connection
Today Story 1. 티어와레이어 2. 웹프로그래밍과엔터프라이즈프로그래밍 3. MVC 모델과웹개발의흐름 4. Spring 3대구성원리와디자인패턴 5대원리 5. AJAX와데이터처리
Round Trip
AJAX Data CSV @@@Jungbo,15400,1100@@Hankyung,26200,1000@@@ XML <kosdaq> <stock> <stockname>jungbo</stockname> <stockprice>15400</stockprice> <prevstockprice>1100</prevstockprice> </stock> <stock> <stockname>hankyung</stockname> <stockprice>26200</stockprice> <prevstockprice>200</prevstockprice> </stock> </kosdaq>
AJAX Data JSON { kosdaq : { stock : [ } } { stockname : Jungbo, stockprice : 15400, prevstockprice : 1100 }, { stockname : Hankyung, stockprice : 26200, prevstockprice : 1000 } ]