2016년 9월 30일 금요일

04day Spring

1.어노테이션으로 aspectj라이브러리를 이용해서 aop를 만들기
폴더구성

pom.xml 에서 라이브러리 추가
<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>

Action.java
package spring;

public interface Action {
 public abstract void sayHello1();
 public abstract void sayHello2();
}

WriteAction.java
package spring;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello1() {
  // TODO Auto-generated method stub
  System.out.println("sayHello1 시작");
  System.out.println("Hello1 " + name);
  System.out.println("sayHello1 끝");
 }
 
 @Override
 public void sayHello2() {
  // TODO Auto-generated method stub
  System.out.println("sayHello2 시작");
  System.out.println("Hello2 " + name);
  System.out.println("sayHello2 끝");
 }

}

LoginAdvice.java
package spring;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;

//xml에서 기술 했던부분을 java클래스에서 기술함
@Aspect
public class LoginAdvice {
 @Pointcut("execution(* sayHello1())")
 private void myTarget(){};
 
 @Around("myTarget()")
 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
  //전처리
  String methodName = joinPoint.getKind();
  StopWatch stopWatch = new StopWatch();
  stopWatch.start(methodName);
  System.out.println("[LOG] Method : "+methodName);
  
  Object rtnObj =joinPoint.proceed();
  
  //후처리
  stopWatch.stop();
  System.out.println("[LOG] Method : "+ methodName);
  System.out.println("[LOG] 시간 : "+ stopWatch.getTotalTimeSeconds());
  
  return rtnObj;
 }
}

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <bean id="action" class="spring.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    <bean id="loginAdvice" class="spring.LoginAdvice" />
    <aop:aspectj-autoproxy />
    
</beans>

ApplicationMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

import spring.Action;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  Action action = (Action)ctx.getBean("action"); //proxy 방식이 아니라서 여기서 코드 수정 안함
  action.sayHello1();
  action.sayHello2();
  
  ctx.close();
 }

}




LoginAdvice.java 사전처리만 추가
package spring;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.StopWatch;

//xml에서 기술 했던부분을 java클래스에서 기술함
@Aspect
public class LoginAdvice {
 @Pointcut("execution(* sayHello1())")
 private void myTarget(){};
 
 @Around("myTarget()")  //around 전후 처리
 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
  //전처리
  String methodName = joinPoint.getKind();
  StopWatch stopWatch = new StopWatch();
  stopWatch.start(methodName);
  System.out.println("[LOG] Method : "+methodName);
  
  Object rtnObj =joinPoint.proceed();
  
  //후처리
  stopWatch.stop();
  System.out.println("[LOG] Method : "+ methodName);
  System.out.println("[LOG] 시간 : "+ stopWatch.getTotalTimeSeconds());
  
  return rtnObj;
 }
 
 @Before("execution(* sayHello2())")  //before  사전처리만
 public void before(){
  System.out.println("[LOG] 전처리만 메서드 호출");
 }
}

ApplicationMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

import spring.Action;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  Action action = (Action)ctx.getBean("action"); //proxy 방식이 아니라서 여기서 코드 수정 안함
  action.sayHello1();
  System.out.println("---------------------");
  action.sayHello2();
  
  ctx.close();
 }

}


2. MVC spring 서블릿프로젝트에 스프링 라이브러리를 복사하는 방법

폴더구성

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>MVCEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 서블릿 설정 -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/webContext.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

webContext.xml
<?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-4.3.xsd">

    <bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="listView1.jsp"></property>
    </bean>
</beans>

index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- index.jsp -->

index.jsp<br />
<a href="list1.do">list1.do</a>

</body>
</html>

listView1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- listView1.jsp -->

listView1.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>


3. webContext에 폴더 경로 설정

폴더구성



web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>MVCEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 서블릿 설정 -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/webContext.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

webContext.xml
<?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-4.3.xsd">
    <!-- 가상 주소에 실제 주소를 연결함 -->
    <bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="listView1.jsp"></property>
    </bean>
    <bean name="/list2.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="listView2.jsp"></property>
    </bean>
    <bean name="/list3.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="./views/listView1.jsp"></property>
    </bean>
    <bean name="/list4.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="/WEB-INF/listView1.jsp"></property>
    </bean>
    <!-- "/board1/list1.do" 가상경로를 만듦 -->
    <bean name="/board1/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="/WEB-INF/listView1.jsp"></property>
    </bean>
</beans>

index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- index.jsp -->

index.jsp<br />
<a href="list1.do">list1.do</a>
<a href="list2.do">list2.do</a>
<a href="list3.do">list3.do</a>
<a href="list4.do">list4.do</a>

<a href="./board1/list1.do">list1.do</a>

</body>
</html>

listView1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- listView1.jsp -->

listView1.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>

listView2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- listView1.jsp -->

listView2.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>

views.listView1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- listView1.jsp -->

views.listView1.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>

WEB-INF/listView1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- listView1.jsp -->

/WEB-INF/listView1.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>


4. 실제주소 입력 단축

폴더구조

webContext2.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
    
    <!-- 실제주소 입력 단축 -->
    <bean name="/list1.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="listView1"></property>
    </bean>
    <bean name="/list2.do" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
        <property name="viewName" value="listView2"></property>
    </bean>
    <!-- 실제주소 앞뒤 문자열 연결 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/" />
    <property name="suffix" value=".jsp" />
    </bean>
</beans>

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>MVCEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 서블릿 설정 -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/webContext2.xml</param-value><!-- 사용할 webContext 파일 설정 -->
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- index.jsp -->

index.jsp<br />
<a href="list1.do">list1.do</a>
<a href="list2.do">list2.do</a>


</body>
</html>


5. 모델만들기

폴더구성


listAction1.java 만들때 Controller 상속받아야 함
package spring;

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

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

import com.sun.swing.internal.plaf.metal.resources.metal;

public class listAction1 implements Controller {

 @Override
 public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("ListAction1 : handleRequest() 호출");
  ModelAndView modelAndView = new ModelAndView();
  modelAndView.setViewName("listView1");
  
  //return new ModelAndView("listView1");
  return modelAndView;
 }

}

listAction2.java
package spring;

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 listAction2 implements Controller {

 @Override
 public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse arg1) throws Exception {
  // TODO Auto-generated method stub
  
  System.out.println("ListAction2 : handleRequest() 호출");
  return new ModelAndView("redirect:/index.jsp"); //바로 보냄
 }

}

webContext3.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
    
    <bean name="/list1.do" class="spring.listAction1" />
    <bean name="/list2.do" class="spring.listAction2" />
    
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

web.xml 에서 사용할 webContext파일 명 바꿔줌
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>MVCEx01</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- 서블릿 설정 -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/webContext3.xml</param-value><!-- 사용할 webContext 파일 설정 -->
      </init-param>
      <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>*.do</url-pattern>
  </servlet-mapping>
</web-app>

index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- index.jsp -->

index.jsp<br />
<a href="list1.do">list1.do</a>
<a href="list2.do">list2.do</a>


</body>
</html>

/WEB-INF/listView1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- /WEB-INF/listView1.jsp -->

/WEB-INF/listView1.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>

/WEB-INF/listView2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- /WEB-INF/listView2.jsp -->

/WEB-INF/listView2.jsp<br />
<a href="javascript:history.back()">뒤로가기</a>

</body>
</html>


2016년 9월 29일 목요일

03day Spring

1. 어노테이션기법으로 context.xml 빈파일을 대체하는 방법

폴더구조


WriteAction.java
package spring6;

public class WriteAction {
 
 public WriteAction() {
  // 겟빈이 디폴트로 부르는 기본 생성자
  System.out.println("디폴트 생성자 호출");
 }

 public void sayHello(String name){
  System.out.println(name + "님 안녕하세요");
 }

}

Config.java 어노테이션 설정 파일
package spring6;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {
 @Bean
 public WriteAction action1(){
  return new WriteAction();
 }
}

ApplicationMain.java
package spring6;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // 어노테이션 기법으로 스프링 빈객체를 만듦
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
  
  WriteAction action1 =(WriteAction)ctx.getBean("action1");
  action1.sayHello("홍길동");
 }

}


2. 어노테이션 옵션추가


Config.java
package spring6;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {
 @Bean
 public WriteAction action1(){
  return new WriteAction();
 }
 
 @Bean(name="action3") //메서드의 이름을 바꿈
 public WriteAction action2(){
  return new WriteAction();
 }
}

ApplicationMain.java
package spring6;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // 어노테이션 기법으로 스프링 빈객체를 만듦
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
  
  WriteAction action1 =(WriteAction)ctx.getBean("action1");
  action1.sayHello("홍길동");
  
  WriteAction action3 =(WriteAction)ctx.getBean("action3"); //바뀐 메서드이름을 써야함 action2 쓰면 에러남
  action3.sayHello("박문수");
 }

}


3. 오버로딩 생성자 사용


WriteAction.java
package spring6;

public class WriteAction {
 
 public WriteAction() {
  // 겟빈이 디폴트로 부르는 기본 생성자
  System.out.println("디폴트 생성자 호출");
 }
 
 public WriteAction(String name){
  System.out.println("오버로딩 생성자 호출");
 }
 
 public void sayHello(String name){
  System.out.println(name + "님 안녕하세요");
 }

}

Config.java
package spring6;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {
 @Bean
 public WriteAction action1(){
  return new WriteAction();
 }
 
 @Bean(name="action3") //메서드의 이름을 바꿈
 public WriteAction action2(){
  return new WriteAction();
 }
 
 @Bean
 public WriteAction action4(){
  return new WriteAction("성춘향"); //오버로딩 생성자 호출
 }
}

ApplicationMain.java
package spring6;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // 어노테이션 기법으로 스프링 빈객체를 만듦
  AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);

 }

}


4. AOP 관점 지향 프로그래밍 ---di(의존성 주입)를 이용해서 aop를 만듦

폴더구성


Action.java
package spring1;

public interface Action {
 public abstract void sayHello();
}

WriteAction.java
package spring1;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello() {
  // TODO Auto-generated method stub
  System.out.println("sayHello 시작");
  System.out.println("Hello " + name);
  System.out.println("sayHello 끝");
 }

}

LoginAdvice.java 인터페이스 MethodInterceptor 상속받음

package spring1;

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

//서블릿의 필터와 같은 역할을 함 ( 전처리와 후처리 담당 )
public class LoginAdvice implements MethodInterceptor {

 @Override
 public Object invoke(MethodInvocation arg0) throws Throwable {
  //전처리 구간
  System.out.println("전처리 구간");
  Object rtnObj = arg0.proceed();
  
  //후처리 구간
  
  System.out.println("후처리 구간");
  return rtnObj;
 }

}

context.xml
<?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-4.1.xsd">
    
    <!-- 전후처리 함수가있는 클래스 -->
    <bean id="loginAdvice" class="spring1.LoginAdvice" />
    <!-- 전후처리 빈 -->
    <bean id="advice" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <!-- 공통 관심사를 구현하는 관점의 메서드를 advice라고 하며 각 어드바이스는 해당 어드바이스가 적용될 메서드를 지정한 pointcut과 연결됨 -->
        <property name="advice" ref="loginAdvice" /><!-- 전후처리 클래스를 받음 -->
        <property name="pointcut"><!-- 전후처리를 어느 메서드에 적용할 것인지 찾음 -->
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern" value=".*sayHello.*" /><!-- 정규표현식 sayHello 메서드를 찾음 -->
            </bean>
        </property>
    </bean>
    
    <!-- 그냥 빈 -->
    <bean id="action" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <!-- 전처리 후처리 빈 + 그냥 빈 -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="action" /><!-- 그냥 빈을 받음 -->
        <property name="interceptorNames">
            <list>
                <value>advice</value><!-- 전처리 후처리 빈을 받음 -->
            </list>
        </property>
    </bean>
    
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  //Action action = (Action)ctx.getBean("action"); //그냥 호출
  Action action = (Action)ctx.getBean("proxy"); //전처리 후처리 있는 빈 호출
  action.sayHello();
  
  ctx.close();
 }

}


5. 전후처리를 메소드 명에따라서 선별적으로 적용함


Action.java
package spring1;

public interface Action {
 public abstract void sayHello1();
 public abstract void sayHello2();
}

WriteAction.java
package spring1;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello1() {
  // TODO Auto-generated method stub
  System.out.println("sayHello1 시작");
  System.out.println("Hello1 " + name);
  System.out.println("sayHello1 끝");
 }
 
 @Override
 public void sayHello2() {
  // TODO Auto-generated method stub
  System.out.println("sayHello2 시작");
  System.out.println("Hello2 " + name);
  System.out.println("sayHello2 끝");
 }

}

LoginAdvice.java
package spring1;

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

//서블릿의 필터와 같은 역할을 함 ( 전처리와 후처리 담당 )
public class LoginAdvice implements MethodInterceptor {

 @Override
 public Object invoke(MethodInvocation arg0) throws Throwable {
  //전처리 구간
  System.out.println("전처리 구간");
  Object rtnObj = arg0.proceed();
  
  //후처리 구간
  
  System.out.println("후처리 구간");
  return rtnObj;
 }

}

context.xml
<?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-4.1.xsd">
    
    <!-- 전후처리 함수가있는 클래스 -->
    <bean id="loginAdvice" class="spring1.LoginAdvice" />
    <!-- 전후처리 빈 -->
    <bean id="advice" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <property name="advice" ref="loginAdvice" />
        <property name="pointcut">
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern" value=".*sayHello1.*" /><!-- 정규표현식 sayHello1 메서드를 찾음 -->
            </bean>
        </property>
    </bean>
    
    <!-- 그냥 빈 -->
    <bean id="action" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <!-- 전처리 후처리 빈 + 그냥 빈 -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="action" />
        <property name="interceptorNames">
            <list>
                <value>advice</value>
            </list>
        </property>
    </bean>
    
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  //Action action = (Action)ctx.getBean("action"); //그냥 호출
  Action action = (Action)ctx.getBean("proxy"); //전처리 후처리 있는 빈 호출
  action.sayHello1();
  System.out.println();
  
  action.sayHello2();
  
  ctx.close();
 }

}


6.전후처리에 메소드가동 시간을 측정하는 처리

폴더구성


Action.java
package spring1;

public interface Action {
 public abstract void sayHello1();
 public abstract void sayHello2();
}

WriteAction.java
package spring1;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello1() {
  // TODO Auto-generated method stub
  System.out.println("sayHello1 시작");
  System.out.println("Hello1 " + name);
  System.out.println("sayHello1 끝");
 }
 
 @Override
 public void sayHello2() {
  // TODO Auto-generated method stub
  System.out.println("sayHello2 시작");
  System.out.println("Hello2 " + name);
  System.out.println("sayHello2 끝");
 }

}

LoginAdvice.java
package spring1;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

//서블릿의 필터와 같은 역할을 함 ( 전처리와 후처리 담당 )
public class LoginAdvice implements MethodInterceptor {

 @Override
 public Object invoke(MethodInvocation arg0) throws Throwable {
  //전처리 구간에서 함수적으로 처리할 수있음
  System.out.println("-----------------전처리 구간");
  
  String methodeName = arg0.getMethod().getName();
  StopWatch stopWatch = new StopWatch();
  stopWatch.start(methodeName);
  
  System.out.println("[LOG] 1차 advice 호출 시작");
  System.out.println("[LOG] 호출 Method명  : " + methodeName);
  System.out.println("-------------------------");
  Object rtnObj = arg0.proceed(); //null로 바꾸면 전후처리 안에 아무것도 안 넣음
  
  //후처리 구간
  
  System.out.println("-----------------후처리 구간");
  stopWatch.stop();
  
  System.out.println("[LOG] 처리시간 : " + stopWatch.getTotalTimeSeconds());
  System.out.println("[LOG] 호출 Method명 : " + methodeName+" 종료");
  System.out.println("-------------------------");
  return rtnObj;
 }

}

context.xml
<?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-4.1.xsd">
    
    <!-- 전후처리 함수가있는 클래스 -->
    <bean id="loginAdvice" class="spring1.LoginAdvice" />
    <!-- 전후처리 빈 -->
    <bean id="advice" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <!-- 공통 관심사를 구현하는 관점의 메서드를 advice라고 하며 각 어드바이스는 해당 어드바이스가 적용될 메서드를 지정한 pointcut과 연결됨 -->
        <property name="advice" ref="loginAdvice" /><!-- 전후처리 클래스를 받음 -->
        <property name="pointcut"><!-- 전후처리를 어느 메서드에 적용할 것인지 찾음 -->
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern" value=".*sayHello1.*" /><!-- 정규표현식 sayHello1 메서드를 찾음 -->
            </bean>
        </property>
    </bean>
    
    <!-- 그냥 빈 -->
    <bean id="action" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <!-- 전처리 후처리 빈 + 그냥 빈 -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="action" /><!-- 전후처리할 타겟에 그냥 빈을 받음 -->
        <property name="interceptorNames">
            <list>
                <value>advice</value><!-- 전처리 후처리 빈을 받음 -->
            </list>
        </property>
    </bean>
    
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  //Action action = (Action)ctx.getBean("action"); //그냥 호출
  Action action = (Action)ctx.getBean("proxy"); //전처리 후처리 있는 빈 호출
  action.sayHello1();
  System.out.println();
  
  action.sayHello2();
  
  ctx.close();
 }

}


7. 여러가지 전후처리 클래스 적용하기

폴더구성


Action.java
package spring1;

public interface Action {
 public abstract void sayHello1();
 public abstract void sayHello2();
}

WriteAction.java
package spring1;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello1() {
  // TODO Auto-generated method stub
  System.out.println("sayHello1 시작");
  System.out.println("Hello1 " + name);
  System.out.println("sayHello1 끝");
 }
 
 @Override
 public void sayHello2() {
  // TODO Auto-generated method stub
  System.out.println("sayHello2 시작");
  System.out.println("Hello2 " + name);
  System.out.println("sayHello2 끝");
 }

}

LoginAdvice.java
package spring1;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

//서블릿의 필터와 같은 역할을 함 ( 전처리와 후처리 담당 )
public class LoginAdvice implements MethodInterceptor {

 @Override
 public Object invoke(MethodInvocation arg0) throws Throwable {
  //전처리 구간에서 함수적으로 처리할 수있음
  System.out.println("전처리 구간1");

  Object rtnObj = arg0.proceed(); //null로 바꾸면 전후처리 안에 아무것도 안 넣음
  
  //후처리 구간
  
  System.out.println("후처리 구간1");

  return rtnObj;
 }

}

LoginAdvice2.java
package spring1;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

//서블릿의 필터와 같은 역할을 함 ( 전처리와 후처리 담당 )
public class LoginAdvice2 implements MethodInterceptor {

 @Override
 public Object invoke(MethodInvocation arg0) throws Throwable {
  System.out.println("전처리 구간2");

  Object rtnObj = arg0.proceed();
  
  //후처리 구간
  
  System.out.println("후처리 구간2");

  return rtnObj;
 }

}

context.xml
<?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-4.1.xsd">
    
    <!-- 전후처리 함수가있는 클래스 -->
    <bean id="loginAdvice" class="spring1.LoginAdvice" />
    <!-- 전후처리2 함수가있는 클래스 -->
    <bean id="loginAdvice2" class="spring1.LoginAdvice2" />
    <!-- 전후처리 빈 -->
    <bean id="advice" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <!-- 공통 관심사를 구현하는 관점의 메서드를 advice라고 하며 각 어드바이스는 해당 어드바이스가 적용될 메서드를 지정한 pointcut과 연결됨 -->
        <property name="advice" ref="loginAdvice" /><!-- 전후처리 클래스를 받음 -->
        <property name="pointcut"><!-- 전후처리를 어느 메서드에 적용할 것인지 찾음 -->
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern" value=".*sayHello1.*" /><!-- 정규표현식 sayHello1 메서드를 찾음 -->
            </bean>
        </property>
    </bean>
    <!-- 전후처리2 빈 -->
    <bean id="advice2" class="org.springframework.aop.support.DefaultPointcutAdvisor">
        <!-- 공통 관심사를 구현하는 관점의 메서드를 advice라고 하며 각 어드바이스는 해당 어드바이스가 적용될 메서드를 지정한 pointcut과 연결됨 -->
        <property name="advice" ref="loginAdvice2" /><!-- 전후처리 클래스를 받음 -->
        <property name="pointcut"><!-- 전후처리를 어느 메서드에 적용할 것인지 찾음 -->
            <bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
                <property name="pattern" value=".*sayHello1.*" /><!-- 정규표현식 sayHello1 메서드를 찾음 -->
            </bean>
        </property>
    </bean>
    
    <!-- 그냥 빈 -->
    <bean id="action" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <!-- 전처리 후처리 빈 + 그냥 빈 -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="action" /><!-- 전후처리할 타겟에 그냥 빈을 받음 -->
        <property name="interceptorNames">
            <list> <!--처리 순서가 앞에것 먼저됨 -->
                <value>advice</value><!-- 전처리 후처리 빈을 받음 -->
                <value>advice2</value><!-- 전처리 후처리 빈을 받음 -->
            </list>
        </property>
    </bean>
    
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  //Action action = (Action)ctx.getBean("action"); //그냥 호출
  Action action = (Action)ctx.getBean("proxy"); //전처리 후처리 있는 빈 호출
  action.sayHello1();
  System.out.println();
  
  action.sayHello2();
  
  ctx.close();
 }

}


8. aspectj라이브러리를 이용해서 aop를 만듦

폴더구성


pom.xml에 라이브러리 추가
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.samples</groupId>
  <artifactId>AOPEx02</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <properties>

        <!-- Generic properties -->
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Spring -->
        <spring-framework.version>4.2.3.RELEASE</spring-framework.version>

        <!-- Hibernate / JPA -->
        <hibernate.version>4.2.1.Final</hibernate.version>

        <!-- Logging -->
        <logback.version>1.0.13</logback.version>
        <slf4j.version>1.7.5</slf4j.version>

        <!-- Test -->
        <junit.version>4.11</junit.version>

    </properties>
    
    <dependencies>
        <!-- Spring and Transactions -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>

        <!-- Logging with SLF4J & LogBack -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>${logback.version}</version>
            <scope>runtime</scope>
        </dependency>

        <!-- Hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>${hibernate.version}</version>
        </dependency>

        
        <!-- Test Artifacts -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring-framework.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <!-- 라이브러리 추가 -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>
    </dependencies>    
</project>


Action.java
package spring1;

public interface Action {
 public abstract void sayHello1();
 public abstract void sayHello2();
}

WriteAction.java
package spring1;

public class WriteAction implements Action {
 private String name;
 
 public void setName(String name){
  this.name = name;
 }
 
 @Override
 public void sayHello1() {
  // TODO Auto-generated method stub
  System.out.println("sayHello1 시작");
  System.out.println("Hello1 " + name);
  System.out.println("sayHello1 끝");
 }
 
 @Override
 public void sayHello2() {
  // TODO Auto-generated method stub
  System.out.println("sayHello2 시작");
  System.out.println("Hello2 " + name);
  System.out.println("sayHello2 끝");
 }

}

LoginAdvice.java
package spring1;

import org.aspectj.lang.ProceedingJoinPoint;

public class LoginAdvice {
 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
  System.out.println("전처리 구간");
  Object rtnObj = joinPoint.proceed();
  
  System.out.println("후처리 구간");
  return rtnObj;
 }
}

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <bean id="action1" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <bean id="loginAdvice" class="spring1.LoginAdvice"></bean>
    
    <!-- 전처리 하고 싶으면 적고, 안하고 싶으면 삭제하면 됨 -->
    <aop:config>
        <aop:aspect id="logAspect" ref="loginAdvice">
            <aop:around method="logAround" pointcut="execution(* sayHello1())"/>
        </aop:aspect>
    </aop:config>
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  Action action = (Action)ctx.getBean("action1"); //proxy 방식이 아니라서 여기서 코드 수정 안함
  action.sayHello1();
  
  ctx.close();
 }

}




전처리만 실행하고 싶을 때
LoginAdvice.java
package spring1;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class LoginAdvice {
 public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
  System.out.println("전처리 구간");
  Object rtnObj = joinPoint.proceed();
  
  System.out.println("후처리 구간");
  return rtnObj;
 }
 public void before(JoinPoint joinpoint) throws Throwable {
  String data = joinpoint.getSignature().getName(); //joinpoint로 실행메서드 파악가능
  System.out.println("전처리만 실행 : "+data);
 }
}

context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <bean id="action1" class="spring1.WriteAction">
        <property name="name">
            <value>홍길동</value>
        </property>
    </bean>
    
    <bean id="loginAdvice" class="spring1.LoginAdvice"></bean>
    
    <!-- 전처리 하고 싶으면 적고, 안하고 싶으면 삭제하면 됨 -->
    <aop:config>
        <aop:aspect id="logAspect" ref="loginAdvice">
            <!-- <aop:around method="logAround" pointcut="execution(* sayHello1())"/> --><!-- 전후처리 모두 -->
            <aop:before method="before" pointcut="execution(* sayHello1())"/><!-- 전처리만 -->
        </aop:aspect>
    </aop:config>
</beans>

ApplicationMain.java
package spring1;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring1/context.xml");
  
  Action action = (Action)ctx.getBean("action1"); //proxy 방식이 아니라서 여기서 코드 수정 안함
  action.sayHello1();
  
  ctx.close();
 }

}

2016년 9월 28일 수요일

02day Spring

1. Bean 옵션에 따라서 인스턴스를 생성시키는 방법이 달라짐

폴더구성

HelloSpring.java
package spring;

public class HelloSpring {
 
 public HelloSpring() {
  // TODO Auto-generated constructor stub
  System.out.println("생성자 출력");
 }
 
 public void sayHello(String name){
  System.out.println(name + "님 안녕하세요");
 }
}

context.xml
<?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-4.1.xsd">

    <bean id="helloBean1" class="spring.HelloSpring" scope="prototype"/><!-- prototype쓰면 겟빈을 하는 순간 인스턴스화 각각이루어짐  -->
    <bean id="helloBean2" class="spring.HelloSpring" scope="singleton"/>
    
</beans>

HelloSpringMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

public class HelloSpringMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  //prototype쓰면 겟빈을 하는 순간 인스턴스화 각각이루어짐
  HelloSpring helloSpring1 = (HelloSpring)ctx.getBean("helloBean1", HelloSpring.class);
  HelloSpring helloSpring2 = (HelloSpring)ctx.getBean("helloBean1", HelloSpring.class);

  //객체 주소 출력
  System.out.println(helloSpring1);
  System.out.println(helloSpring2);
  
  
  ctx.close();
 }

}

생성자가 bean의 singleton때문에 generic때 한번, prototype 인스턴스 호출 때문에 2번 이루어짐

HelloSpringMain2.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

public class HelloSpringMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  //singleton쓰면 겟빈을 하는 순간 인스턴스 한번 생성
  HelloSpring helloSpring1 = (HelloSpring)ctx.getBean("helloBean2", HelloSpring.class);
  HelloSpring helloSpring2 = (HelloSpring)ctx.getBean("helloBean2", HelloSpring.class);
  
  //객체 주소 출력
  System.out.println(helloSpring1);
  System.out.println(helloSpring2);
  
  
  ctx.close();
 }

}

생성자가 bean의 singleton때문에 generic때 한번 이루어짐

2. 생성자 주입- 사용자 정의 생성자를 부르는 법

폴더구성

WriteAction.java
package spring3;

public class WriteAction {
 private String name;
 private String age;
 
 public WriteAction() {
  // 겟빈이 디폴트로 부르는 기본 생성자
  System.out.println("디폴트 생성자 호출");
 }

 public WriteAction(String name) {
  this.name = name;
  System.out.println("유저 생성자 호출 1");
 }
 
 public WriteAction(String name, String age) {
  this.name = name;
  System.out.println("유저 생성자 호출 2");
 }
 
}

context.xml
<?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-4.1.xsd">

    <bean id="action1" class="spring3.WriteAction" scope="prototype"/><!-- 디폴트 생성자 부름 -->
    <bean id="action2" class="spring3.WriteAction" scope="prototype"><!-- 사용자 정의 생성자 1 부름 -->
        <constructor-arg value="홍길동" />
    </bean>
    <bean id="action3" class="spring3.WriteAction" scope="prototype"><!-- 사용자 정의 생성자 2 부름 -->
        <constructor-arg value="홍길동" />
        <constructor-arg value="30" />
    </bean>
</beans>

ApplicationMain.java
package spring3;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // singleton 이면 Generic 할때 모든 생성자를 다부름
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring3/context.xml");
  
  //WriteAction action1 = (WriteAction)ctx.getBean("action1");
  //WriteAction action2 = (WriteAction)ctx.getBean("action2");
  WriteAction action3 = (WriteAction)ctx.getBean("action3");
  
  ctx.close();
 }

}



**bean이 singleton인 경우 -한개의 생성자만 사용하더라도 모두다 호출됨
context.xml
<?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-4.1.xsd">

    <bean id="action1" class="spring3.WriteAction"/><!-- 디폴트 생성자 부름 -->
    <bean id="action2" class="spring3.WriteAction"><!-- 사용자 정의 생성자 1 부름 -->
        <constructor-arg value="홍길동" />
    </bean>
    <bean id="action3" class="spring3.WriteAction"><!-- 사용자 정의 생성자 2 부름 -->
        <constructor-arg value="홍길동" />
        <constructor-arg value="30" />
    </bean>

</beans>

ApplicationMain.java
package spring3;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // singleton 이면 Generic 할때 모든 생성자를 다부름
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring3/context.xml");
  
  //WriteAction action1 = (WriteAction)ctx.getBean("action1");
  //WriteAction action2 = (WriteAction)ctx.getBean("action2");
  WriteAction action3 = (WriteAction)ctx.getBean("action3");
  
  ctx.close();
 }

}




자바프로젝트와 비교

WriteAction.java

public class WriteAction {
 private String name;
 
 public WriteAction() {
  // 겟빈이 디폴트로 부르는 기본 생성자
  System.out.println("디폴트 생성자");
 }

 public WriteAction(String name) {
  this.name = name;
  System.out.println("유저 생성자 호출");
 }
 
}

ApplicationMain.java

public class ApplicationMain {
 public static void main(String[] args) {
  //기본생성자
  WriteAction action1 = new WriteAction();
  //사용자정의 생성자
  WriteAction action2 = new WriteAction("홍길동");
 }
}


3. 생성자 매개변수에 TO클래스가 들어가는 경우

폴더구성

BoardTO.java
package spring3;

public class BoardTO {
 public BoardTO() {
  System.out.println("BoardTO 생성자 호출");
 }
}

WriteAction.java
package spring3;

public class WriteAction {
 private String name;
 private String age;
 
 public WriteAction() {
  // 겟빈이 디폴트로 부르는 기본 생성자
  System.out.println("디폴트 생성자 호출");
 }

 public WriteAction(String name) {
  this.name = name;
  System.out.println("유저 생성자 호출 1");
 }
 
 public WriteAction(String name, String age) {
  this.name = name;
  System.out.println("유저 생성자 호출 2");
 }
 public WriteAction(BoardTO to){
  System.out.println("유저 생성자 호출 3");
 }
}

context.xml
<?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-4.1.xsd">

    <bean id="action1" class="spring3.WriteAction" scope="prototype"/><!-- 디폴트 생성자 부름 -->
    <bean id="action2" class="spring3.WriteAction" scope="prototype"><!-- 사용자 정의 생성자 1 부름 -->
        <constructor-arg value="홍길동" />
    </bean>
    <bean id="action3" class="spring3.WriteAction" scope="prototype"><!-- 사용자 정의 생성자 2 부름 -->
        <constructor-arg value="홍길동" />
        <constructor-arg value="30" />
    </bean>
    <bean id="to" class="spring3.BoardTO" scope="prototype" /><!-- 사용할 TO클래스를 먼저 정의함 -->
    <bean id="action4" class="spring3.WriteAction" scope="prototype"><!-- 사용자 정의 생성자 3 부름 -->
        <constructor-arg ref="to" />
    </bean>
</beans>

ApplicationMain.java
package spring3;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // singleton 이면 Generic 할때 모든 생성자를 다부름
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring3/context.xml");
  
  //WriteAction action1 = (WriteAction)ctx.getBean("action1");
  //WriteAction action2 = (WriteAction)ctx.getBean("action2");
  //WriteAction action3 = (WriteAction)ctx.getBean("action3");
  WriteAction action4 = (WriteAction)ctx.getBean("action4");
  
  ctx.close();
 }

}


4.boardTO 객체 사용

폴더구성


BoardTO.java
package spring4;

public class BoardTO {
 private int seq;
 private String subject;
 private String content;
 
 public int getSeq() {
  return seq;
 }
 public void setSeq(int seq) {
  this.seq = seq;
 }
 public String getSubject() {
  return subject;
 }
 public void setSubject(String subject) {
  this.subject = subject;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
}

context.xml
<?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-4.1.xsd">

    <bean id="to" class="spring4.BoardTO">
        <property name="seq" value="1" />
        <property name="subject" value="제목" />
        <property name="content" value="내용" />
    </bean>
</beans>

ApplicationMain.java
package spring4;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring4/context.xml");
  
  BoardTO to = (BoardTO)ctx.getBean("to");
  System.out.println(to.getSeq());
  System.out.println(to.getSubject());
  System.out.println(to.getContent());
  
  to.setSeq(2); //BoardTO를 바꾸면 context.xml에도 적용이 됨
  System.out.println(to.getSeq());
  to = (BoardTO)ctx.getBean("to");
  System.out.println(to.getSeq());
  
  ctx.close();
  System.out.println(to.getSeq());//객체가 소멸되었지만 일시적으로 찍힐 수 있음
 }

}



자바 프로젝트와 비교
폴더구성

BoardTO.java
package spring2;

public class BoardTO {
 private int seq;
 private String subject;
 private String content;
 
 public int getSeq() {
  return seq;
 }
 public void setSeq(int seq) {
  this.seq = seq;
 }
 public String getSubject() {
  return subject;
 }
 public void setSubject(String subject) {
  this.subject = subject;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
}

ApplicationMain.java
package spring2;

public class ApplicationMain {
 public static void main(String[] args) {
  BoardTO to = new BoardTO();
  
  to.setSeq(1);
  to.setSubject("제목");
  to.setContent("내용");
  
  System.out.println(to.getSeq());
  System.out.println(to.getSubject());
  System.out.println(to.getContent());
 }
}


5.ListTO 객체의 사용

폴더구성


BoardTO.java
package spring5;

public class BoardTO {
 private int seq;
 private String subject;
 private String content;
 
 public int getSeq() {
  return seq;
 }
 public void setSeq(int seq) {
  this.seq = seq;
 }
 public String getSubject() {
  return subject;
 }
 public void setSubject(String subject) {
  this.subject = subject;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
}

BoardListTO.java
package spring5;

import java.util.ArrayList;

public class BoardListTO {
    private ArrayList<String> users;
    private ArrayList<BoardTO> boardLists;
    
    public ArrayList<String> getUsers() {
        return users;
    }
    public void setUsers(ArrayList<String> users) {
        this.users = users;
    }
    public ArrayList<BoardTO> getBoardLists() {
        return boardLists;
    }
    public void setBoardLists(ArrayList<BoardTO> boardLists) {
        this.boardLists = boardLists;
    }
}

context.xml
<?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-4.1.xsd">
    <bean id="to1" class="spring5.BoardTO" scope="prototype"><!-- boardListTO에 넣을 boardTO 생성 -->
        <property name="seq" value="1" />
        <property name="subject" value="제목1" />
        <property name="content" value="내용1" />
    </bean>
    <bean id="to2" class="spring5.BoardTO" scope="prototype">
        <property name="seq" value="2" />
        <property name="subject" value="제목2" />
        <property name="content" value="내용2" />
    </bean>
    
    <bean id="listTO" class="spring5.BoardListTO" scope="prototype"><!-- boardListTO 생성 -->
        <property name="users"><!-- 직접 boardListTO에 입력-->
            <list>
                <value>홍길동</value>
                <value>박문수</value>
            </list>
        </property>
        <property name="boardLists"><!-- 위에서 정의한 boardTO를 boardListTO에 입력-->
            <list>
                <ref bean="to1"/>
                <ref bean="to2"/>
            </list>
        </property>
    </bean>
</beans>

ApplicationMain.java
package spring5;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring5/context.xml");
  
  BoardListTO listTO = (BoardListTO)ctx.getBean("listTO");
  for(String user : listTO.getUsers()){
   System.out.println(user);
  }
  
  for(BoardTO to : listTO.getBoardLists()){
   System.out.println(to.getSeq());
   System.out.println(to.getSubject());
   System.out.println(to.getContent());
  }
  
  ctx.close();
 }

}



자바프로젝트와 비교
폴더구성

BoardTO.java
package spring3;

public class BoardTO {
 private int seq;
 private String subject;
 private String content;
 
 public int getSeq() {
  return seq;
 }
 public void setSeq(int seq) {
  this.seq = seq;
 }
 public String getSubject() {
  return subject;
 }
 public void setSubject(String subject) {
  this.subject = subject;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
}

BoardListTo.java
package spring3;

import java.util.ArrayList;

public class BoardListTo {
    private ArrayList<String> users;
    private ArrayList<BoardTO> boardLists;
    
    public ArrayList<String> getUsers() {
        return users;
    }
    public void setUsers(ArrayList<String> users) {
        this.users = users;
    }
    public ArrayList<BoardTO> getBoardLists() {
        return boardLists;
    }
    public void setBoardLists(ArrayList<BoardTO> boardLists) {
        this.boardLists = boardLists;
    }
}

ApplicationMain.java
package spring3;

import java.util.ArrayList;

public class ApplicationMain {

    public static void main(String[] args) {
        //객체 생성
        ArrayList<String> users = new ArrayList<>();
        users.add("홍길동");
        users.add("박문수");
        
        BoardListTo listTO = new BoardListTo();
        listTO.setUsers(users);
        
        //객체 사용
        for(String user : listTO.getUsers()){
            System.out.println(user);
        }
        
        //객체 생성 (스프링에서 처리하는 부분)
        BoardTO to1 = new BoardTO();
        to1.setSeq(1);
        to1.setSubject("제목1");
        to1.setContent("내용1");
        BoardTO to2 = new BoardTO();
        to2.setSeq(2);
        to2.setSubject("제목2");
        to2.setContent("내용2");
        
        ArrayList<BoardTO> boardLists = new ArrayList<>();
        boardLists.add(to1);
        boardLists.add(to2);
        listTO.setBoardLists(boardLists);
        
        //객체 사용
        for(BoardTO to : listTO.getBoardLists()){
            System.out.println(to.getSeq());
            System.out.println(to.getSubject());
            System.out.println(to.getContent());
        }
        
    }

}


6. 스프링에서 bean을 생성할때 사용되는 메서드와 bean생명주기

폴더구조


Action.java 인터페이스 만듦
package spring;

public interface Action {
 public abstract void sayHello();
}


WriteAction.java 만들때 인터페이스 상속받음
package spring;
//스프링에서 bean만들 때 자동적으로 호출되는 메서드들
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class WriteAction implements Action, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    private String msg;
    private String beanName;
    private BeanFactory beanFactory;
    
    public WriteAction() {
        // TODO Auto-generated constructor stub
        System.out.println("1. 빈의 생성자 실행");
    }
    @Override
    public void destroy() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("9. destroy() 실행");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
        System.out.println("6. afterPropertiesSet() 실행");
    }

    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        // TODO Auto-generated method stub
        System.out.println("4. setBeanFactory() 실행");
        this.beanFactory = arg0;
        System.out.println("\t ->" +beanFactory);
    }

    @Override
    public void setBeanName(String arg0) {
        // TODO Auto-generated method stub
        System.out.println("3. setBeanName() 실행");
        this.beanName = arg0;
        System.out.println("\t ->" +beanName);
    }

    @Override
    public void sayHello() {
        // TODO Auto-generated method stub
        System.out.println("*. sayHello() 실행");
        System.out.println("\t ->" +beanName);
    }

}


context.xml
<?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-4.1.xsd">

    <bean id="action" class="spring.WriteAction" />
</beans>

ApplicationMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  Action action = (Action)ctx.getBean("action");
  action.sayHello();
  
  ctx.close();
 }

}


7. 스프링에서 bean 초기화 및 삭제 메서드 지정

폴더구조


WriteAction.java
package spring;
//스프링에서 bean만들 때 자동적으로 호출되는 메서드들
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class WriteAction implements Action, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    private String msg;
    private String beanName;
    private BeanFactory beanFactory;
    
    public WriteAction() {
        System.out.println("1. 빈의 생성자 실행");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("9. destroy() 실행");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("6. afterPropertiesSet() 실행");
    }

    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("4. setBeanFactory() 실행");
        this.beanFactory = arg0;
        System.out.println("\t -&gt;" +beanFactory);
    }

    @Override
    public void setBeanName(String arg0) {
        System.out.println("3. setBeanName() 실행");
        this.beanName = arg0;
        System.out.println("\t -&gt;" +beanName);
    }

    @Override
    public void sayHello() {
        System.out.println("*. sayHello() 실행");
        System.out.println("\t -&gt;" +beanName);
    }
    //초기화 때 사용할 메서드 지정
    public void init_method(){
        System.out.println("7. init_method() 실행");
    }
    //Bean삭제 때 사용할 메서드 지정
    public void destroy_method(){
        System.out.println("10. destroy_method() 실행");
    }

}

context.xml
<?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-4.1.xsd">
    
    <!-- 초기화와 삭제할때 사용할 메서드 지정 -->
    <bean id="action" class="spring.WriteAction" init-method="init_method" destroy-method="destroy_method" />
</beans>

ApplicationMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  Action action = (Action)ctx.getBean("action");
  action.sayHello();
  
  ctx.close();
 }

}


8. 스프링에서 bean 멤버변수 세팅 메서드 순서

WriteAction.java
package spring;
//스프링에서 bean만들 때 자동적으로 호출되는 메서드들
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class WriteAction implements Action, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    private String msg;
    private String beanName;
    private BeanFactory beanFactory;
    
    public WriteAction() {
        System.out.println("1. 빈의 생성자 실행");
    }
    //setter
    public void setMsg(String msg){
        this.msg = msg;
        System.out.println("2. setMsg() 실행");
    }
    
    @Override
    public void destroy() throws Exception {
        System.out.println("9. destroy() 실행");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("6. afterPropertiesSet() 실행");
        //setter로 멤버변수 세팅 되어있는지 확인하는 메서드
        if(msg ==null){
            System.out.println("멤버변수 필요함");
        }else{
            System.out.println("멤버변수 있음");
        }
    }

    @Override
    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out.println("4. setBeanFactory() 실행");
        this.beanFactory = arg0;
        System.out.println("\t ->" +beanFactory);
    }

    @Override
    public void setBeanName(String arg0) {
        System.out.println("3. setBeanName() 실행");
        this.beanName = arg0;
        System.out.println("\t ->" +beanName);
    }

    @Override
    public void sayHello() {
        System.out.println("*. sayHello() 실행");
        System.out.println("\t ->" +beanName);
    }

    public void init_method(){
        System.out.println("7. init_method() 실행");
    }
    public void destroy_method(){
        System.out.println("10. destroy_method() 실행");
    }

}

context.xml
<?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-4.1.xsd">
    
    <bean id="action" class="spring.WriteAction" init-method="init_method" destroy-method="destroy_method" >
        <property name="msg" value="Hello" /><!-- 멤버변수 세팅 -->
    </bean>
</beans>

ApplicationMain.java
package spring;

import org.springframework.context.support.GenericXmlApplicationContext;

public class ApplicationMain {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:spring/context.xml");
  
  Action action = (Action)ctx.getBean("action");
  action.sayHello();
  
  ctx.close();
 }

}