<configuration>
<typeAliases>
<typeAlias type="pack.model.JikwonDto" alias="dto"/>
</typeAliases>
<!-- DB 연결을 root-context.xml에서 하도록 수정.-->
<mappers>
<mapper resource="pack/mybatis/DataMapper.xml" />
</mappers>
</configuration>
- DataMapper(xml)
<mapper namespace="dev">
<select id="selectJikwonAll" resultType="dto">
select jikwon_no, jikwon_name, jikwon_jik, jikwon_gen, buser_name
from jikwon left outer join buser
on jikwon.buser_num = buser.buser_no
</select>
<select id="selectLoginData" resultType="dto" parameterType="string">
select jikwon_no, jikwon_name
from jikwon
where jikwon_no=#{no}
</select>
</mapper>
- MyDataSource
public class MyDataSource extends DriverManagerDataSource {
public MyDataSource() {
setDriverClassName("org.mariadb.jdbc.Driver");
setUrl("jdbc:mysql://127.0.0.1:3306/test");
setUsername("root");
setPassword("123");
}
}
<body>
<h2>스프링으로 xml 형태의 결과 반환연습</h2>
<a href="member">출발</a><br>
</body>
=> 요청명 member 전달.(GET방식)
- myform.jsp
<body>
<h2>자료입력</h2>
<form action="member" method="post">
name : <input type="text" name="name" value="tom"><br>
age : <input type="text" name="age" value="22"><br>
<input type="submit">
</form>
<hr>
<form action="member_xml" method="post">
name : <input type="text" name="name" value="tom"><br>
age : <input type="text" name="age" value="22"><br>
<input type="submit">
</form>
</body>
=> 상기 <form>태그 요청명 member 전달.(POST방식)
=> 하기 <form>태그요청명 member_xml 전달.(POST방식)
- MemberController
@Controller
public class MemberController {
@RequestMapping(value="member", method = RequestMethod.GET)
public String formBack() {
return "myform";
}
@RequestMapping(value="member", method = RequestMethod.POST)
@ResponseBody // 자바객체를 Http 응답객체로 클라이언트에 전송 가능.
public String submit(@RequestBody String formData) {
// @RequestBody는 요청 몸체(body)에 있는 client의 요청 값을 그대로 받아들임.
System.out.println("formData : "+formData); // name=tom&age=22
formData+="hello";
return formData; // @ResponseBody 사용 시 formData가 가진 값을 클라이언트에게 바로 송신.
}
...
}
=> @RequestBody : 요청의 Boby 값을 변수에 대입. ex) name=tom&age=22
@Controller
public class MemberController {
...
@RequestMapping(value="member_xml", method = RequestMethod.POST)
@ResponseBody
public XmlMessageList submit_xml(@RequestParam("name") String name,
@RequestParam("age") String age) {
System.out.println(name+" "+age);
return getXml(name, age);
}
public XmlMessageList getXml(String name, String age) {
List<XmlMessage> messages = Arrays.asList(
new XmlMessage(name, age),
new XmlMessage("oscar", "25"),
new XmlMessage("emma", "24")
);
return new XmlMessageList(messages);
}
}
=> 요청명 member_xml(Post방식) 일 경우 실행.
=> @ResponseBody : getXml()의 리턴값을 클라이언트에서 출력한다.
=>
- XmlMessage
@XmlAccessorType(XmlAccessType.FIELD)
//@XmlType(name="", propOrder = {"name","age"})
public class XmlMessage {
private String name;
private String age;
public XmlMessage() {
}
public XmlMessage(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
}
- XmlMessageList
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "msg-list") // Root Element 이름 지정
public class XmlMessageList {
@XmlElement(name = "msg")
private List<XmlMessage> messages;
public XmlMessageList() {
}
public XmlMessageList(List<XmlMessage> messages) {
this.messages = messages;
}
public List<XmlMessage> getMessages(){
return messages;
}
}
@Controller
public class SangpumController {
@Autowired
private DataDao dataDao;
@RequestMapping("sangpum")
@ResponseBody // Body를 통채로 송부한다.
public Map<String, Object> abc(){ // JSON은 Map을 리턴해야한다.
List<Map<String, String>> dataList = new ArrayList<Map<String, String>>();
Map<String, String> data = null;
List<SangpumDto> sangList = dataDao.sangpumList(); // DB에서 데이터를 받아온다.
for(SangpumDto s : sangList) {
data = new HashMap<String, String>();
data.put("code", s.getCode()); // key, value 형식으로 DB값을 담는다.
data.put("sang", s.getSang());
data.put("su", s.getSu());
data.put("dan", s.getDan());
dataList.add(data); // List에 Record 값을 넣는다.
}
Map<String, Object> sangpumDatas = new HashMap<String, Object>();
sangpumDatas.put("datas", dataList); // Map에 List를 담아 전송한다.
return sangpumDatas; // JSON은 Map을 리턴해야한다.
}
}
- DataDao
@Repository
public class DataDao extends SqlSessionDaoSupport{
public DataDao(SqlSessionFactory factory) {
setSqlSessionFactory(factory);
}
public List<SangpumDto> sangpumList(){
List<SangpumDto> list = getSqlSession().selectList("selectAll");
return list;
}
}
- SangpumDto
public class SangpumDto {
private String code, sang, su, dan;
//getter/setter
}
@Controller
public class ListController {
@Autowired
private BoardDaoInter boardInter;
private int tot; // 전체 레코드 수
private int plist=5; // 한 페이지 당 행의 수
private int pageCount; // 전체 페이지 수
public ArrayList<BoardDto> getListData(ArrayList<BoardDto> list, int page){
ArrayList<BoardDto> result = new ArrayList<BoardDto>();
int start = (page - 1)*plist; // 해당 페이지의 첫 게시물의 index
int size = plist <= list.size() - start ? plist : list.size() - start;
// 한 페이지에 표시할 데이터가 5개 이하일 경우엔 size가 그 수에 따르도록 조건처리.
for(int i=0; i<size;i++) { // list에 한 페이지당 표시할 데이터만 담아 리턴한다.
result.add(i, list.get(start + i));
}
return result;
}
public int getPageCount() { // get 페이지 수
pageCount = tot/plist;
if(tot%plist > 0 ) pageCount+=1;
return pageCount;
}
@RequestMapping("list")
public Model process(Model model, @RequestParam("page") int page) {
tot = boardInter.totalCnt();
ArrayList<BoardDto> list = boardInter.getList();
ArrayList<BoardDto> result = getListData(list, page);
model.addAttribute("data",result);
model.addAttribute("pageCount",getPageCount());
model.addAttribute("page",page);
//model.addAttribute("data",list); // 페이징 없이 작업할 경우
return model;
}
}
=> totalCnt() :
=> getList() : 전체 List 검색하여 list 리턴.
=> getListData() : 전체 리스트에서 한 페이지 당 표시할 데이터만 리턴값으로 가진다.
=> plist : 한 페이지 당 표시할 레코드 수를 설정.
=> getPageCount() : 페이지의 개수를 리턴.
- BoardBean
public class BoardBean {
private String name,pass,mail,title,cont,bip,bdate;
private int num,readcnt,gnum,onum,nested;
private String searchName, searchValue;
//getter/setter
}
=> FormBean 작성.
- BoardDto
public class BoardDto {
private String name,pass,mail,title,cont,bip,bdate;
private int num,readcnt,gnum,onum,nested;
//getter/setter
}
@Repository
public class BoardDaoImpl extends SqlSessionDaoSupport implements BoardDaoInter {
@Autowired
public BoardDaoImpl(SqlSessionFactory factory) {
setSqlSessionFactory(factory);
}
@Override
public ArrayList<BoardDto> getList() {
return (ArrayList)getSqlSession().selectList("selectList");
}
@Override
public int totalCnt() {
return getSqlSession().selectOne("totalCnt");
}
...
}
=> getList() : board 테이블의 모든 정보 list 리턴.
=> totalCnt() : 레코드 수를 리턴.
<!-- 전체 검색 -->
<select id="selectList" resultType="dto">
select * from board order by gnum desc, onum asc
</select>
<select id="totalCnt" resultType="integer">
select count(*) from board
</select>
=> location.href : 목록버튼 누를 경우 list 출력 창 1 page로 이동.
focus() : 커서가 해당 창으로 이동.
submit() : submit 동작 진행.
- InsertController
@Controller
public class InsertController {
@Autowired
private BoardDaoInter boardInter;
...
@RequestMapping(value="insert", method = RequestMethod.POST)
public String submit(BoardBean bean) {
bean.setBdate();
int newNum = boardInter.currentNum() + 1; // 새로 작성된 글의 번호
bean.setNum(newNum);
bean.setGnum(newNum);
boolean b= boardInter.insert(bean);
if(b) {
return "redirect:/list?page=1";
}else {
return "redirect:/error";
}
}
}
=> POST방식 요청명 insert 받을 경우 실행.
=> <form>태그 데이터 FormBean에 set.
=> setBdate() : Calendar객체를 이용하여 오늘 날짜를 set한다.
=> currentNum() : 현재 테이블의 num값중 가장 큰 값을 받아와 +1하여 현재 num가 group num 값을 set한다.
=> insert() : data 추가.
=> insert 성공 시 전체 list 페이지로 이동, 실패 error 페이지로 이동.
public void setBdate() {
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DATE);
this.bdate = year + "-" + month + "-" + day;
}
- BoardDaoImpl
@Repository
public class BoardDaoImpl extends SqlSessionDaoSupport implements BoardDaoInter {
@Autowired
public BoardDaoImpl(SqlSessionFactory factory) {
setSqlSessionFactory(factory);
}
...
@Override
public boolean insert(BoardBean bean) {
int result = getSqlSession().insert("insertData",bean);
if(result>0) {
return true;
}else {
return false;
}
}
...
@Override
public int currentNum() {
//insert시 번호 자동 증가를 위해 현재 레코드 중 가장 큰 번호 얻기.
if(getSqlSession().selectOne("currentNum") == null) {
return 0;
}else {
return getSqlSession().selectOne("currentNum");
}
}
...
}
=> insert() : insert에 성공 시 true, 실패 시 false 리턴.
=> currentNum() : 레코드가 없을 경우 현재 가장 큰 num값을 0으로 리턴.
...
<!-- 추가 -->
<insert id="insertData" parameterType="formBean">
insert into board
values(#{num},#{name},#{pass},#{mail},#{title},#{cont},
#{bip},#{bdate},0,#{gnum},0,0)
</insert>
...
<!-- maxnum -->
<select id="currentNum" resultType="integer">
select max(num) from board
</select>
...
=> Data insert
=> board테이블의 num중 가장 큰 값 리턴.
- ErrorController
@Controller
public class ErrorController {
@RequestMapping("error")
public String err() {
return "error";
}
}
@Controller
public class SearchController {
@Autowired
private BoardDaoInter inter;
@RequestMapping("search")
public ModelAndView searchProcess(BoardBean bean) {
ArrayList<BoardDto> list = inter.getSearch(bean);
ModelAndView view = new ModelAndView("list", "data", list);
view.addObject("page","1");
return view;
}
}
=> list.jsp에서 검색 버튼을 누를 경우 searchName(key), searchValue(key)가 전달된다.
=> getSearch() : searchName(key), searchValue(key)에 맞는 값을 검색하여 리스트로 출력한다.
=> 리턴 값을 list.jsp에 출력.
- BoardDaoImpl
@Repository
public class BoardDaoImpl extends SqlSessionDaoSupport implements BoardDaoInter {
@Autowired
public BoardDaoImpl(SqlSessionFactory factory) {
setSqlSessionFactory(factory);
}
...
@Override
public ArrayList<BoardDto> getSearch(BoardBean bean) {
return (ArrayList)getSqlSession().selectList("searchList", bean);
}
...
}
=> getSearch() : 검색 후 ArrayList 리턴.
- DataMapper.xml
...
<!-- 카워드 검색 -->
<select id="searchList" parameterType="formBean" resultType="dto">
select * from board
where ${searchName} like concat('%',#{searchValue},'%')
order by gnum desc, onum asc
</select>
...
=> searchName의 Column에서 searchValue의 키워드가 있을 경우 리스트를 리턴한다.
@Controller
public class DetailController {
@Autowired
private BoardDaoInter inter;
@RequestMapping("detail")
public ModelAndView detailProcess(@RequestParam("num") String num,
@RequestParam("page") String page) {
// 조회수 증가 작업 선행
boolean b = inter.updateReadcnt(num);
// 상세보기 진행 후 jsp로 출력
ModelAndView view = new ModelAndView("detail");
view.addObject("data", inter.getDetail(num));
view.addObject("page", page);
return view;
}
}
=> list.jsp에서 제목을 누를 경우 요청명 detail로 num과 page 값을 전달받는다.
=> @RequestParam : request.getParameter()와 동일.
=> updateReadcnt() : 조회수를 +1한다.
=> getDetail() : 해당 num의 한 레코드 값을 리턴하여 detail.jsp 실행.
-BoardDaoImpl
@Repository
public class BoardDaoImpl extends SqlSessionDaoSupport implements BoardDaoInter {
@Autowired
public BoardDaoImpl(SqlSessionFactory factory) {
setSqlSessionFactory(factory);
}
...
@Override
public BoardDto getDetail(String num) {
// 글 내용보기, 글 수정 시 데이터 받아오기
return getSqlSession().selectOne("selectOne",num);
}
...
@Override
public boolean updateReadcnt(String num) {
//상세보기 전 조회수 증가
int result = getSqlSession().update("updateReadcnt",num);
if(result>0) {
return true;
}else {
return false;
}
}
...
}
=> getDetail() : 게시글의 내용을 받아온다.
=> updateReadcnt() : 업데이트 성공시 true, 실패 시 false 리턴
- DataMapper.xml
...
<!-- 번호로 검색 -->
<select id="selectOne" parameterType="string" resultType="dto">
select * from board where num=#{num}
</select>
...
<!-- readcnt -->
<update id="updateReadcnt" parameterType="string">
update board set readcnt=readcnt + 1
where num=#{num}
</update>
...
<mapper namespace="dev">
<select id="selectAll" resultType="dto">
select num, name, addr from mem
</select>
<select id="selectPart" parameterType="String" resultType="dto">
select num, name, addr from mem
where num=#{num}
</select>
<insert id="insertData" parameterType="formBean">
insert into mem values(#{num}, #{name}, #{addr})
</insert>
<update id="updateData" parameterType="formBean">
update mem set name=#{name}, addr=#{addr}
where num=#{num}
</update>
<delete id="deleteData" parameterType="String">
delete from mem where num=#{num}
</delete>
</mapper>
=> Login에 성공할 경우 redirect로 클라이언트에서 요청을 실행한 것과 같이 실행하여야한다. (forward를 사용하지
않음). Redirect로 list.jsp를 실행한다.
- LoginForm
@Component
public class LoginForm {
private String userid; // <form>태그의 name속성값과 동일하게 변수를 가진다.
private String passwd;
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
=> <form>태그의 name속성값과 동일하게 변수를 가지도록 작성한다. FormBean은 client의 요청을 처리할 때 사용
한다. DTO는 DB 자료를 처리할 때 사용. (용도에 따라 관례적으로 FormBean과 DTO를 사용한다)
- ListController
@Controller
public class ListController {
@RequestMapping("list")
public ModelAndView aaa() {
ModelAndView view = new ModelAndView("list");
view.addObject("msg", "로그인 성공으로 하고 뭔가를 출력함");
return view;
}
}
@Controller // 클라이언트로 부터 요청 받을 경우 동작
public class ListController {
@Autowired
private DataDao dataDao;
@RequestMapping("testdb") // url mapping
public ModelAndView listProcess() {
ArrayList<SangpumDto> list = dataDao.getDataAll();
return new ModelAndView("list", "datas", list); // list.jsp에 연결.
}
}
=> @Controller : 클라이언트로 부터 요청 받을 경우 동작.
@Autowired : setter injection 기능 수행.
@RequestMapping("url명") : url명과 동일한 url을 받을 경우 실행.
dataDao의 getDataAll()를 실행한 list값을 "datas" key에 넣어 실행한다.
- SangpumDto
public class SangpumDto {
private String code, sang, su, dan;
//getter/setter
}
@Controller // 클라이언트로 부터 요청 받을 경우 동작
public class ListController {
@Autowired
private DataDao dataDao;
@RequestMapping("testdb") // url mapping
public ModelAndView listProcess() {
ArrayList<SangpumDto> list = dataDao.getDataAll();
return new ModelAndView("list", "datas", list); // list.jsp에 연결.
}
}
=> DataSource와 동일
- SangpumDto
public class SangpumDto {
private String code, sang, su, dan;
//getter/setter
}
=> DataSource와 동일
- DataSourceMaria
@Repository() // DB연동
//@Repository("dataSource")
public class DataSourceMaria extends DriverManagerDataSource{
public DataSourceMaria() {
setDriverClassName("org.mariadb.jdbc.Driver");
setUrl("jdbc:mysql://127.0.0.1:3306/test");
setUsername("root");
setPassword("123");
}
}
=> DataSource와 동일
- DataDao
@Repository // DB 연결.
public class DataDao extends JdbcDaoSupport{
//@Autowired
//private DataSourceMaria dataSourceMaria; // DataDao에 주입됨.
//DataSource를 JdbcDaoSupport가 가지고 있으로 생성자를 이용한다.
public DataDao(DriverManagerDataSource dataSource) {
setDataSource(dataSource);
}
public List<SangpumDto> getDataAll(){
String sql="select * from sangdata";
return getJdbcTemplate().query(sql, new ItemRowMapper());
}
class ItemRowMapper implements RowMapper{
@Override
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
SangpumDto dto = new SangpumDto();
dto.setCode(rs.getString("code"));
dto.setSang(rs.getString("sang"));
dto.setSu(rs.getString("su"));
dto.setDan(rs.getString("dan"));
return dto;
}
}
}
=> extends JdbcDaoSupport : JdbcDaoSupport 상속 받아 기능을 수행한다.
=> @Autowird를 사용하면 DataDao객체에 dataSource가 setter injection됨으로 해당 기능이 정상동작하지않는다.
정상동작을 위해선 상속을 받고있는 JdbcDaoSupport객체에 setter injection을 하여야한다. 생성자를 이용하여
DataDao객체가 생성되면 setDataSource()가 실행되도록 하여 JdbcDaoSupport객체에 dataSource를 setter
=> 공유자원을 관리하는 root-context.xml에서 DB연결을 하도록, Sql문 mapping하는 DataMapper.xml관련 설정을
제외하고 삭제.
=> DataMapper파일과 alias를 정의한다.
- DataMapper.xml
<mapper namespace="dev">
<select id="selectAll" resultType="dto">
select * from sangdata
</select>
<select id="selectSearch" parameterType="formBean" resultType="dto">
select code, sang, su, dan from sangdata
where sang like concat('%',#{searchValue},'%')
</select>
</mapper>
=> sql문과 연결되는 Mapper 파일을 작성한다.(<mapper>태그 내부에 sql문을 형식에 맞춰 작성)
=> <select> : select문 작성 시 사용되는 태그. (id속성 - 외부에서 호출할 이름 / resultType - sql문을 실행한 결과
Type / parameterType속성 - 외부로 부터 받을 매개변수의 타입, #{변수명}에 매개변수가 대입된다.)
=> like concat('%', 검색어, '%') : 검색어가 포함된 결과 반환. ( like %검색어%)
@Controller
//@ComponentScan("pack.model")
public class ListController {
@Autowired // setter injection
private SangpumInter sangpumInter; // 다형성 사용
@RequestMapping("list")
public Model process(Model model){
model.addAttribute("data", sangpumInter.list());
// Model객체는 addAttribe(key, value) 메소드를 사용하여 값을 전달.
return model; // 받은 요청명 그대로 송부한다.
}
}
=> @Controller : Controller 기능 수행 (servlet 동작)
=> "list" url 받을 경우 동작한다. list()메소드를 실행한 결과를 "data" key에 넣어 list.jsp에 리턴한다.
- SangpumDto
public class SangpumDto {
private String code,sang, su, dan;
//setter, getter
}
=> DB연동에 사용되는 데이터는 Dto로 작성.(select)
- SangpumBean
public class SangpumBean {
// formBean : 수정, 삭제 등의 작업이 있다면 code, sang, su, dan도 처리
// 검색용
private String searchValue;
public String getSearchValue() {
return searchValue;
}
public void setSearchValue(String searchValue) {
this.searchValue = searchValue;
}
}
@Controller
//@ComponentScan("pack.model")
public class ListController {
@Autowired // setter injection
private SangpumInter sangpumInter; // 다형성 사용
@RequestMapping("list")
public Model process(Model model){
model.addAttribute("data", sangpumInter.list());
// Model객체는 addAttribe(key, value) 메소드를 사용하여 값을 전달.
return model; // 받은 요청명 그대로 송부한다.
}
}
=> xml방식과 동일
- SangpumDto
public class SangpumDto {
private String code,sang, su, dan;
//setter, getter
}
=> xml방식과 동일
- SangpumBean
public class SangpumBean {
// formBean : 수정, 삭제 등의 작업이 있다면 code, sang, su, dan도 처리
// 검색용
private String searchValue;
public String getSearchValue() {
return searchValue;
}
public void setSearchValue(String searchValue) {
this.searchValue = searchValue;
}
}
// MyBatis SQL mapping interface file
public interface SangpumAnnoInter {
@Select("select * from sangdata")
public List<SangpumDto> selectAllData();
@Select(" select code, sang, su, dan from sangdata where sang like concat('%',#{searchValue},'%')")
public List<SangpumDto> selectSearch(SangpumBean bean);
}
① Client요청을 Controller로 연결하기 ② 공유 객체 사용 ③ 패턴을 사용한 경로 매핑 ④ @annotation을 이용한 Controller호출 ⑤ Spring MVC Project를 사용 ⑥ @RequestParam 사용(get) * Controller 값 처리(기존) : getParameter() * Controller 값 처리(어노테이션 사용) * get 방식은 한글이 안깨지나 post 방식사용시 한글이 깨진다. Encording을 하여 한글 깨짐을 방지한다. ⑦ FormBean, @ModelAttribute 사용(post) * Controller 값 처리(기존) : getParameter() * Controller 값 처리(FormBean 사용) * Controller 값 처리(@ModelAttribute 사용)
=> 어노테이션 사용시 <context:component-scan>를 사용한다. pack package의 어노테이션이 동작하도록 한다.
- HelloController * Controller implemets(상속)을 사용할 경우
public class HelloController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("veiw1"); // veiw1.jsp에 연결
modelAndView.addObject("message", "hello"); // 모델에 다녀왔다 가정. // key-value 전달.
return modelAndView;
}
}
=> hello-servlet.xml/world-servlet.xml에서 연결한 hello.do 요청 발생 시 실행된다.
=> handlerRequest() 메소드를 오버라이딩하여 request를 처리한다.
=> setVieName("파일명")으로 view1에 연결된다. .hello-servlet.xml 파일의 ViewResover 처리로 /views/view1.jsp파일이
연결된다.
=> addObject(key, value)를 이용하여 값을 전달한다.
* @Controller(어노테이션)을 사용할 경우
@Controller
@RequestMapping("hello.do") // 모든 메소드가 수행된다.
public class HelloController{
@RequestMapping(method=RequestMethod.GET)
//@RequestMapping("hello.do") // 해당 메소드만 실행된다.
public ModelAndView aaa() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view1");
modelAndView.addObject("message", "hello aaa");
return modelAndView;
}
@RequestMapping(method=RequestMethod.POST)
//@RequestMapping("hello.do")
public ModelAndView bbb() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view1");
modelAndView.addObject("message", "hello bbb");
return modelAndView;
}
}
=> hello-servlet.xml의 <context:component-scan>태그로 인해 @Controller가 동작한다.
@Controller : 클라이언트 요청에 따라 해당 클래스가 Controller동작을 하게된다.
@RequestMapping("요청명") : 요청명에 해당하는 요청이 들어올 경우 클래스가 실행된다.
@RequestMapping(method=RequestMethod.GET) : Get방식의 요청이 들어올때만 실행하게 한다.
@RequestMapping(method=RequestMethod.POST) : Post방식의 요청이 들어올때만 실행하게 한다.
=> ModelAndView객체를 리턴하도록 하여 값을 전달한다. 메소드명을 임의 지정 가능하다.
- WorldController * Controller implemets(상속)을 사용할 경우
public class WorldController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view2"); // veiw1.jsp에 연결
modelAndView.addObject("message", "hi world"); // 모델에 다녀왔다 가정. // key-value 전달.
return modelAndView;
}
}
=> HelloController와 동일
* @Controller(어노테이션)을 사용할 경우
@Controller
public class WorldController{
@RequestMapping({"/world.do","/good*.*","/hi/nice.do"}) // 여러개의 요청을 받을 수 있음.
//@RequestMapping("world.do")
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view2"); // veiw1.jsp에 연결
modelAndView.addObject("message", "hi world"); // 모델에 다녀왔다 가정. key-value 전달.
return modelAndView;
}
@RequestMapping(value="/korea.do", method=RequestMethod.GET) // GET만 받을 수 있다.
//@RequestMapping({"/korea.do"})// Get과 Post를 모두 받을 수 있다.
public ModelAndView handleRequest2(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view2"); // veiw1.jsp에 연결
modelAndView.addObject("message", "hi world korea"); // 모델에 다녀왔다 가정. key-value 전달.
return modelAndView;
}
@RequestMapping(value="/usa.*", method=RequestMethod.POST) // POST만 받을 수 있다.
//@RequestMapping(value="/usa.*", method=RequestMethod.GET) // GET만 받을 수 있다.
//@RequestMapping({"/usa.*"})
public ModelAndView handleRequest3(HttpServletRequest request, HttpServletResponse response)
throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("view2"); // veiw1.jsp에 연결
modelAndView.addObject("message", "hi world usa"); // 모델에 다녀왔다 가정. key-value 전달.
return modelAndView;
}
}
=> @RequestMapping({요청명1, 요청명2,..}) : 배열을 사용하여 여러개의 요청명을 받을 수 있다.
@RequestMapping(value="요청명", method=RequestMethod.GET) : 요청과 method 방식을 설정할 수 있다.
요청명에 * 를 사용하여 복수의 요청을 받을 수 있다.
- view1.jsp / view2.jsp
<body>
hello 결과 : ${requestScope.message}
</body>
=> Controller에서 addObject()메소드로 전달한 value를 key를 사용하여 받을 수 있다. (EL 사용 - ${key})
2) 공유 객체 사용
= spr4_share
- index.html
<body>
클래스 간 자원 공유<br>
<a href="hello.do">요청 1</a><br>
<a href="world.kor">요청2</a><br>
</body>
- web.xml
<!-- WebApplicationContext보다 먼저 수행 : 공유 자원 설정시 필요 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
=> applicationContext.xml에 공유자원을 설정한다.
<!-- WebApplicationContext에 의해 자동 수행 -->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- <load-on-startup> init() 메소드 호출 순서 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>world</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>world</servlet-name>
<url-pattern>*.kor</url-pattern>
<!-- <url-pattern>/</url-pattern> 모든 요청사항 -->
</servlet-mapping>
=> *.do 요청과 hello-servlet.xml 연결
=> *.kor요청과 world-servlet.xml 연결
- applicationContext.xml
<!-- 공유 자원 객체 생성 -->
<bean id="sharedData" class="pack.SharedData">
<property name = "shared" value="스프링 프로젝트 공유자원입니다."/>
</bean>
=> setter injection을 이용하여 공유자원 객체 shard에 value를 설정한다.
=>SimSimpleUrlHandlerMapping사용하여 <prop>에 경로 매핑 가능하다.
=> ?는 글자 갯수. * 복수개의 문자를 나타냄.
=> HelloController mapping의 name을 <prop>의 값으로 받아 패턴을 연결한다.
- HelloController
public class HelloController implements Controller{
private HelloModel helloModel;
//setter injection
public void setHelloModel(HelloModel helloModel) {
this.helloModel = helloModel;
}
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// 모델 만들고 모델과 통신하기
String result = helloModel.getGreeting();
ModelAndView modelAndView = new ModelAndView();
//ModelAndView modelAndView = new ModelAndView("hello"); // ViewFile명
modelAndView.setViewName("hello");
modelAndView.addObject("result",result); // forword 방식(default)
//modelAndView.setViewName("redirect:/views/hello.jsp?result='d'"); // reditect 방식
return modelAndView;
}
}
=> Controller를 상속받고 handleRequest 오버라이딩하여 요청사항을 처리한다. => 기본 방식을 forward로 하여 /views/hello.jsp에 addObject(key, value)로 값을 전달한다. => setViewName("redirect:/views/hello.jsp")으로 redirect 가능하다.
@Controller
public class SangpumController {
@RequestMapping(value="sangpum", method=RequestMethod.POST)
public ModelAndView submit(HttpServletRequest request) {
String sang = request.getParameter("sang");
String su = request.getParameter("su");
String dan = request.getParameter("dan");
System.out.println(sang+" "+" "+su+" "+dan);
ModelAndView view = new ModelAndView();
view.setViewName("result");
view.addObject("data","good");
return view;
}
}
* Controller 값 처리(FormBean 사용)
@Controller
public class SangpumController {
@RequestMapping(value="sangpum", method=RequestMethod.POST)
public ModelAndView submit(SangpumBean bean) { // 지역 변수
//클라이언트로 부터 들어오는 데이터 양이 많을 경우 사용(form bean)
System.out.println(bean.getSang()+" "+" "+bean.getSu()+" "+bean.getDan());
ModelAndView view = new ModelAndView();
view.setViewName("result");
view.addObject("data","good");
return view;
}
}
=> 매개변수로 FormBean을 사용하여 값을 전달한다. bean의 범위는 {}안으로 지역변수로 사용된다.
* Controller 값 처리(@ModelAttribute 사용)
@Controller
public class SangpumController {
@Autowired // setter injection
private SangpumModel sanpumModel;
@RequestMapping(value="sangpum", method=RequestMethod.POST)
//public ModelAndView submit(SangpumBean bean) { // 지역 변수
public ModelAndView submit(@ModelAttribute("bean") SangpumBean bean) { // 전역변수
//클라이언트로 부터 들어오는 데이터 양이 많을 경우 사용(form bean)
System.out.println(bean.getSang()+" "+" "+bean.getSu()+" "+bean.getDan());
ModelAndView view = new ModelAndView();
view.setViewName("result");
view.addObject("data",sanpumModel.computeSangpum(bean));
return view;
}
}
=> 매개변수로 @ModelAttribute을 사용시 bean의 범위는 전역변수로 사용되어 addObject() 메소드를 사용하지않아도
다른 파일에서 접근이 가능하다.
- SangpumBean
@Component
public class SangpumBean { // form bean
private String sang; // 클라이언트로 부터 전달되어 오는 요청 Parameter값과 변수명을 동일하게 가져간다.
private int su, dan;
public String getSang() {
return sang;
}
public void setSang(String sang) {
this.sang = sang;
}
public int getSu() {
return su;
}
public void setSu(int su) {
this.su = su;
}
public int getDan() {
return dan;
}
public void setDan(int dan) {
this.dan = dan;
}
}
=> Form Bean 정의. Form Bean의 멤버변수는 <form>태그 하위 태그 name의 값과 동일하게 가져간다.
- SangpumModel
@Component // 객체생성
public class SangpumModel { // 비지니스 로직 처리를 하는 모델 영역의 클래스
public String computeSangpum(SangpumBean bean) {
int price = bean.getSu() * bean.getDan();
String data = "품명" + bean.getSang() + " , 금액은 "+price;
return data;
}
}
- result.jsp
<body>
post 결과 : ${data}
<br>
${bean.sang}
</body>
public class StartController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView : DB 처리 결과를 기억, 출력을 위한 view 파일명 기억
System.out.println("StartController handleRequest()수행");
//return new ModelAndView("list"); // 생성자
//모델과 통신하기 생략
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("list"); // setter. forward 방식으로 파일 요청 처리 (default)
//request.setAttribute("key", value); // servlet에서 사용하는 방법.
modelAndView.addObject("say", "messages");//모델과 통신 후 얻어진 결과를 기억했다 가정.(request)
return modelAndView;
}
}
- list.jsp
기존
<%
String str = (String)request.getAttribute("say");
out.println(str);%>
EL
${say} ${requestScope.say}
@Controller // Conponent와 동일. Cotroller에 사용.
public class StartController{
@RequestMapping("start.do")
public ModelAndView handleStart(HttpServletRequest request, HttpServletResponse response) throws Exception {
// ModelAndView : DB 처리 결과를 기억, 출력을 위한 view 파일명 기억
System.out.println("StartController handleStart()수행 - annotaion");
//return new ModelAndView("list"); // 생성자
//모델과 통신하기 생략
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("list"); // setter. forward 방식으로 파일 요청 처리 (default)
//request.setAttribute("key", value); // servlet에서 사용하는 방법.
modelAndView.addObject("say", "messages - annotaion");//모델과 통신 후 얻어진 결과를 기억했다 가정.(request)
return modelAndView;
}
}
<!-- DriverManagerDataSource를 상속받은 db 연결 class 객체 생성. -->
<bean id="dataSource" class="pack.model.DataSourceMaria"></bean>
<!-- db연결 클래스 객체 생성 -->
<bean id="sangpumImpl" class="pack.model.SangpumImpl">
<!-- JdbcDaoSupport을 상속받았기 때문에 별도로 dataSource setter를 정의하지않아도 setter주입을 할 수 있다. -->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 객체생성 -->
<bean id="businessImpl" class="pack.business.BusinessImpl">
<property name="sangpumInter" ref="sangpumImpl"/>
</bean>
public interface HelloInter {
void hello();
void hi();
}
- HelloInterImpl
public class HelloInterImpl implements HelloInter{
public HelloInterImpl() {
System.out.println("HelloInterImpl 생성자");
}
public void hello() {
System.out.println("hello 처리");
}
public void hi() {
System.out.println("hi 처리");
}
}
- WriteInter
public interface WriteInter {
void write();
}
- WriteInterImpl
public class WriteInterImpl implements WriteInter{ // 핵심 로직을 가진 클래스
public WriteInterImpl() {
System.out.println("WriteInterImpl 생성자");
}
public void write() {
System.out.println("write 수행");
}
}
- MyAspect
public class MyAspect { // 관심사항을 가진 클래스
public void myLogOn() {
System.out.println("핵심 메소드 수행전 로그온 작업");
}
public void myLogOut() {
System.out.println("핵심 메소드 수행후 로그아웃 작업");
}
public void mySecurity() {
System.out.println("핵심 메소드 수행전 보안설정");
}
}
- AspectProcess
public class AspectProcess { // 여러개의 관심사항들을 모아 처리하는 클래스
private MyAspect myAspect; // 관심사항 클래스. 여러개 가능
public void setMyAspect(MyAspect myAspect) {
this.myAspect = myAspect;
}
public Object logging(ProceedingJoinPoint joinPoint) throws Throwable{
Object object = null;
myAspect.myLogOn();
object = joinPoint.proceed(); // 메타파일에서 설정한 핵심 메소드 수행.
myAspect.myLogOut();
return object;
}
public Object logging2(ProceedingJoinPoint joinPoint) throws Throwable{
Object object = null;
myAspect.mySecurity();
object = joinPoint.proceed(); // 메타파일에서 설정한 핵심 메소드 수행.
return object;
}
}
=> 핵심 로직의 wri로 시작하고 메개변수가 0개 이상인 메소드가 호출될때 AspectProcess(Aspect를 처리하는) 클래스의 logging() 메소드가 실행된다.
=> 핵심 로직의 hel로 시작하고 메개변수가 0개 이상인 메소드 또는 hi로 시작하는 메소드가 호출될때 AspectProcess클래스의 logging2() 메소드가 실행된다.
- ArticleInter
public interface ArticleInter {
void select();
}
- ArticleDao
//@Component
//@Repository
@Repository("articleDao")
public class ArticleDao implements ArticleInter{
public void select() {
System.out.println("db의 상품 자료를 read");
}
}
- LogicInter
public interface LogicInter {
void selectData_process();
}
- LogicImpl
public class LogicImpl implements LogicInter{
private ArticleInter articleInter;
public LogicImpl() {
}
public LogicImpl(ArticleInter articleInter) {
this.articleInter = articleInter;
}
public void selectData_process() {
System.out.println("selectData_proces 수행");
articleInter.select();
}
}
@Service
public class LogicImpl implements LogicInter{
@Autowired
//@Qualifier("aticleDao")
private ArticleInter articleInter;
public void selectData_process() {
System.out.println("selectData_proces 수행");
articleInter.select();
}
}
- ProfileAdvice
public class ProfileAdvice { // Advice, Aspect
public Object abc(ProceedingJoinPoint joinPoint) throws Throwable{
//핵심 메소드 이름 얻기
String methodName = joinPoint.getSignature().toString();
System.out.println(methodName+" 시작 전 작업");
Object object = joinPoint.proceed(); // 핵심 메소드
System.out.println(methodName+" 처리 후 작업");
return object;
}
}
@Aspect
@Component
public class ProfileAdvice { // Advice, Aspect
@Around("execution(public void selectData_process())")
public Object abc(ProceedingJoinPoint joinPoint) throws Throwable{
//핵심 메소드 이름 얻기
String methodName = joinPoint.getSignature().toString();
System.out.println(methodName+" 시작 전 작업");
Object object = joinPoint.proceed(); // 핵심 메소드
System.out.println(methodName+" 처리 후 작업");
return object;
}
}
- main
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop2.xml");
LogicInter inter = (LogicInter)context.getBean("logicImpl");
inter.selectData_process();
}
=> 핵심로직의 selectData_process()메소드 호출 시 profileAdvice클래스의 abc()메소드가 호출.
<!-- 객체 생성 : 어노테이션 -->
<context:component-scan base-package="aop3"/>
<!-- Aop 설정 -->
<aop:aspectj-autoproxy/>
* 스프링 AOP에서 용어
- Joinpoint : ‘클래스의 인스턴스 생성 시점’, ‘메소드 호출 시점’ 및 ‘예외 발생 시점’ 과 같이 어플리케이션을 실행할 때 특정 작업이 시작되는 시점을 의미.
- Advice : 조인포인트에 삽입되어 동작할 수 있는 코드를 말함.
- Pointcut : 여러 개의 조인포인트를 하나로 결합한(묶은) 것을 말함.
- Advisor : 어드바이스와 포인트컷을 하나로 묶어 취급한 것을 말함.
- Weaving : 어드바이스를 핵심 로직 코드에 삽입하는 것을 말함.
- Target : 핵심 로직을 구현하는 클레스.
- Aspect : 여러 객체에 공통으로 적용되는 공통 관점 사항을 말함.
1) AOP 구현
- LogicInter
public interface LogicInter {
void startProcess();
}
- LogicImpl
@Service // @Component와 동일하지만 가독성을 위해 Service기능을 사용하면 @Service를 사용.
public class LogicImpl implements LogicInter{
public LogicImpl() {
}
public void startProcess() {
System.out.println("핵심 로직 수행");
}
}
- aop4.xml
<!-- 어노테이션을 사용하여 객체 생성 -->
<context:component-scan base-package="aop4"/>
<!-- aop를 사용하도록 설정 -->
<aop:aspectj-autoproxy/>
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("aop4.xml");
LogicInter inter = (LogicInter)context.getBean("logicImpl");
// getBean의 매개변수 : @객체 생성할 클래스명을 첫글자 소문자로 변경하여 생성.
inter.startProcess();
}
- RunAspect
// 아이디가 같으면 핵심로직 수행, 다르면 수행하지않도록 구현.
@Component
@Aspect // 독립적으로 동작할 관심 로직 클래스에 사용
public class RunAspect {
@Around("execution(public void startProcess())")
// 핵심로직의 메소드를 선택. 해당메소드 호출시 관심 메소드 호출.
//@Around는 핵심로직 실행 전/후 모두 기능을 추가할 수 있다.
public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("AOP 시작 : 핵심 로직 처리전 id 검증");
System.out.print("input id : ");
Scanner scanner = new Scanner(System.in);
String id = scanner.nextLine();
if(! id.equalsIgnoreCase("aa")) { //equalsIgnoreCase() 대소문자 구분하지않고 비교.
System.out.println("id 불일치하여 작업을 종료합니다.");
return null;
}
Object obj = joinPoint.proceed(); // 핵심 로직 수행.
return obj;
}
}
@Component
@Aspect
@Around("excution(핵심 로직의 메소드)")
public Object 관심메소드명(ProceedingJoinPoint joinPoint) throws Throwable{ .. }
=> id나 name 둘중 무엇을 사용해도 상관없으며, <ref bean="name">에서 name을 호출가능.
② 생성자 호출
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("money_init.xml");
MyInter inter = (MyInter)context.getBean("myProcess");
inter.inputMoney();
inter.showResult();
}
}
=> ApplicationContext 객체 생성시 xml에 연결된 모든 생성자가 호출되며, 각 객체가 생성된다.
=> context의 getBean()메소드로 객체를 get하여 메소드를 사용한다.
=> getBean() 메소드의 리턴값은 Object로 다형성을 사용하여 캐스팅하여 객체를 대입한다.
=> getBean() 리턴 객체도 다형성을 사용하여 interface 객체에 대입하여 사용하는 것을 지향한다.
③ MVC 패턴 및 다형성 활용한 프로그래밍
pakage
Controller(Servlet)
Model(Dto, Dao-sql)
Interface
BusinessInterface
ModelInterface
↑
↑
Class
BusinessClass
ModelClass
=> 다형성을 갖춘 MVC Pattern 작성을 지향하여 프로그래밍한다.
=> Controller의 Business Class에서 Model Interface를 호출하여 사용한다.
=> 각 모델은 다형성을 활용하여 테이블에 따른 Sql문을 호출하여 DB와 연결된다.
=> [src.main/java]에 작성한다.
-Business Interface
public interface MyInter {
void inputMoney();
void showResult();
}
-Business Class
public class MyProcess implements MyInter{
private MoneyInter inter;
private int result[];
public MyProcess(MoneyInter inter) {
this.inter = inter;
}
public void inputMoney() {
//키보드로 금액입력
try {
InputStreamReader reader = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(reader);
int myMoney=0;
System.out.println("금액입력");
String data = br.readLine();
myMoney = Integer.parseInt(data);
result = inter.calcMoney(myMoney);
} catch (Exception e) {
System.out.println("inputMoney err "+e);
}
}
public void showResult() {
//계산이 끝난 배열 자료 출력.
System.out.println("만원 : "+result[0]+"개");
System.out.println("천원 : "+result[1]+"개");
System.out.println("백원 : "+result[2]+"개");
System.out.println("십원 : "+result[3]+"개");
System.out.println("일원 : "+result[4]+"개");
}
}
=> 생성자에 모델의 interface 객체를 매개변수로 받아 사용.
- Model Interface
public interface MoneyInter {
int[] calcMoney(int money);
}
- Model Class
public class MoneyCalc implements MoneyInter{
public MoneyCalc() {
}
public int[] calcMoney(int money) {
//단위별 금액 건수 계산용
int result[] = new int[5];
int temp=0;
int len = result.length;
for(int i=0; i<len;i++) {
if(i == 0) {
result[i] = money/(int)Math.pow(10, (len-1-i));
temp=money%(int)Math.pow(10, (len-1-i));
continue;
}
result[i] = temp/(int)Math.pow(10, (len-1-i));
temp=temp%(int)Math.pow(10, (len-1-i));
}
return result;
}
}
③ 생성자 주입(construnctor injection)
- ShowData(Dao)
public class ShowData {
public String toAlias() {
return "홍길동";
}
public String toHobby() {
return "운동";
}
}
- MyProcess(Controller)
public class MyProcess { // 포함으로 약결합 진행
private int age;
private String name;
private ShowData showData; // Class Type
public MyProcess(int age, String name, ShowData showData) {
this.age = age;
this.name = name;
this.showData = showData;
}
public void printData() {
System.out.println(name+age+showData.toAlias()+showData.toHobby());
}
}
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("anno1.xml");
Abc abc = (Abc)context.getBean("abc");
abc.printData();
}
② @Component : 객체 생성
- SenderInter
public interface SenderInter{
void show();
}
- Sender
@Component // 객체 생성
public class Sender implements SenderInter{
public void show() {
System.out.println("show메소드 수행");
}
}
- Sender2
//@Component = @Component("Sender2")// 객체 생성
@Component("별명")
public class Sender2 implements SenderInter{
public void show() {
System.out.println("Sender2의 show메소드 수행");
}
}
③ @Service : @Component와 동일하나 Business 로직에서 사용한다.
④ @Autowired : setter가 내부적으로 정의되며, type에 의한 mapping 진행.
⑤ @Qualifier("아이디") : type에 대하여 mapping시 동일한 타입(같은 부모를 상속받는 자식) 객체가 복수인 경우
Qualifier의 아이디에 명시한 아이디로 mapping한다.
- SenderProcess
//@Component
//@Service
@Service("SenderProcess") //Component와 동일
public class SenderProcess { // 서비스를 하는 비지니스 로직
private String name = "tom";
@Autowired // xml의 type에 대한 mapping.
//@Qualifier("sender2") // 동일한 타입의 객체(상속받는 자식 객체)가 복수인 경우 id로 mapping
@Qualifier("별명")
private SenderInter senderInter;
//public void setSender(Sender sender) { // @Autowired사용시 삭제가능
// this.sender = sender;
//}
public void displayData() {
System.out.println("displayData의 name : " + name);
senderInter.show();
}
}
- xml
<context:annotation-config/> // @어노테이션을 사용가능하게 한다.
<bean id="senderProcess" class="anno2.SenderProcess"/>
<bean id="sender" class="anno2.Sender"/>
<bean id="sender2" class="anno2.Sender2"/>
// SenderInter를 상속하는 class가 복수가 되면 type으로 mapping하기 때문에 식별자가 필요하다.
<bean class="anno2.Sender"/>
// type에 대한 mapping으로 id가 없어도 mapping된다.
<context:annotation-config/> // 생략 가능
<context:component-scan base-package="anno2"/> // pakage의 @Component, @Service가 작성된 class의 Bean을 생성.
- main
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("anno2.xml");
SenderProcess senderProcess = (SenderProcess)context.getBean("senderProcess");
senderProcess.displayData();
}