### : 목차 구분 기호
--- : 목차 내에 항목 구분 기호
@@@ : 태그 용도 
,,, : 같은 목차 내에 구분 기호

목차
1. 이론 및 정보
2. 설정 및 그 밖에
3. 소스코드 또는 실습
4. 과제

###################################
1. 이론 및 정보
-----------------------------------
모듈, 컴퍼넌트, 빈 - 큰 단위의 모듈
모듈은 분리된 단위
모듈의 최소 단위 메서드
----------------------------------- 
라이프 사이클
5. BeanPostProcessor - bean 실행 되기 전
          Object postProcessAfterInitializer(Object bean, String beanName) - 8번
          Object postProcessBeforeInitializer(Object bean, String beanName) - 6번

상속을 받아서 서브클래싱을 해줘야 사용가능

DefaultListableBeanFactory 방식으로 현재 사용중

따로 만든 class CustomBeanPostProcessor implements BeanPostProcessor 를 
생성해서 라이프 사이클에 붙여 줄 수 있는 메서드를 DefaultListableBeanFactory 가
가지고 있음

----------------------------------- 
* Bean 생성 방법

1. XML에 등록
          <bean>
          ------
          <bean id="" class="" />
          인스턴스 주소 값을 id값이 참조한다
               <property name="setter의 set빼고 소문자로 시작" [value="" | ref=""]>
                    <value>...</value>
                    or
                    <ref bean="id 값이 들어감" or local=""/> - 대부분 bean을 사용
                    or
                    <ref bean="bean.Test"/> -> Bean을 생성하면서 넣음, 내부 Bean
               </property>

               <constructor-arg value="" [index=""][type=""]></constructor-arg>
          </bean>

          생성자는 매개변수를 여러개 받을 수 있지만
          Bean의 setter 메서드는 한개의 매개변수만 받을 수 있음

2. XML에 등록
          <네임스페이스명:태그명 .../>

          <aop:config></aop:config> - 특별한 목적으로 bean을 만들때 사용
          <bean></bean> - 범용적
          둘의 차이가 있음

          또한 aop 사용하려면 
          xmlns:aop="http://www.springframework.org/schema/aop"
          필요함

          이러한 태그들을 전용태그라고 함
          <aop:config></aop:config>
          <context:annotation-config></context:annotation-config>
          <bean></bean>  

3. 자동인식을 이용한 빈 생성 : 스테레오 타입의 어노테이션(자바코드를 축약)과 빈 스캐너

4. 자바코드에 의한 Bean 생성 - XML이 하던 일을 대신하게 만듬 : @Configuration(클래스), @Bean(메서드)
     Configuration은 환경설정을 할 수 있는 클래스가 되도록 만들어 줌

5. 자바코드에 의한 Bean 생성 : 일반클래스(Pojo-Plain old java object), @Bean(메서드)
     pojo는 싱글톤이 아님
 
----------------------------------- 
* Namespace 
Java에서 패키지를 의미
----------------------------------- 
* JDK에 따른 어노테이션 문제

JDK 5.0에서 어노테이션이 불안정
인터페이스에서 물려받은 것은 @Override를 안쓰고
클래스에서 물려받은 것만 @Override를 씀
JDK 6.0에서는 인터페이스에서 물려받은 것은 @Override를 쓰임

그래서 5.0에 문제가 되는 @Override를 전부 지워야 함


프로젝트 프로퍼티 설정




이런식으로 변경 가능

----------------------------------- 
@Component
클래스 위에 적어 놓으면
Component로 자동으로 스캐너가 읽는다
이름을 지어주지 않으면 자동으로 이름을 짓는데
클래스 명으로 하는데 단! 첫글자는 소문자
이름을 지정하는 방법 @Component("msgEn")


빈 스캐너가 필요

스캐너 만드는 방법 2가지

1. 기본적인 방식 
     메인에서 applicationcontext를 이용

2. XML에 스캔 범위를 지정
     <context:component-scan base-package="basic08"></context:component-scan>

----------------------------------- 
* Servlet 3.0 부터는 web.xml이 필요없게 만들어 줌

이유는 web.xml 내용이 다시 reflection으로 인해
자바 코드로 바뀌는데 애당초 xml말고 자바 클래스로 바꾸자가 취지임

그래서 3.0 부터는 안만들어도 됨

----------------------------------- 
* Bean은 기본적으로 SingleTon으로 생성됨
Attribute : scope
The scope of this bean: typically "singleton"

/basic/src/main/java/basic09/App.java
를 실행 시켜 보면
new FileOutputter() 를 두번 호출해서 두개가 생성되야 하는데
한개만 생성 되는 것을 확인 할 수 있음

----------------------------------- 
* Bean의 의존 관계 설정 방법(DI 패턴 설정)

1) XML에 등록해서 설정 (Bean 생성 방법의 1번)
2) 자동 와이어링 방식
     a) Attribute
          - 둘 중에 한개만 사용가능!
          i) byName 
               - 관례를 이용한 방식, bean의 이름과 property의 이름이 동일할 때 자동 연결해주는 방식
               - basic10의 xml에 설정을 넣으면 변수의 이름과 같은 bean id를 찾아서 연결
          ii) byType
               - 같은 타입의 변수를 찾아서 가도록 연결


     b) Annotation
          - 아래 두개의 기능은 똑같음
          - 연결하기 위해서는 필요한 스캐너가 있음, 아래는 예시 
          (<context:component-scan base-package="basic10"/>)
          i) @Resource
               - JSR-250(Java 문법 규칙) 스펙에 정의가 되어있음, 자바 문법 어디서든 사용가능
               - 기본값이 bean의 이름으로 연결(byName), 이름이 똑같지 않아도 선택된 것과 최대한 연결하려고함
               - 같은 이름이 없으면 같은 타입을 찾으려고 함
               - 변수 선언부 위에 있으면 setter없이도 가능
          ii) @Autowired
               - Spring에 스펙에 정의가 되어있음, 스프링에서만 쓰일 수 있음
               - 기본값이 bean의 타입으로 연결(byType)
               - spring 전용이라서 많은 도움을 받을 수 있음

----------------------------------- 
* Java Lib 중앙 저장소

mvnrepository.com
annotation 검색
http://mvnrepository.com/artifact/javax.annotation/jsr250-api/1.0

<dependency>
     <groupId>javax.annotation</groupId>
     <artifactId>jsr250-api</artifactId>
     <version>1.0</version>
</dependency>

복사해서 pom.xml 

----------------------------------- 
* AOP(Aspect Oriented Programming) - Spring을 대표하는 기능
다른 언어에서 지원되던 내용을 추가함

AOP에 대한 관심을 충분히 이끌어냈음

관점지향프로그래밍 방식?
객체지향방식을 도와주는 방식
객체지향의 한계를 커버해줌

OOP를 뛰어넘는 개발방식이 나오지는 않았음

OOP로 인해 나온 개발방식? CBD (컴포넌트 기반 개발, component-based development, 모듈 단위로 개발)


OOP는 모듈단위로 개발이 가능하기 때문에 큰 장점이 됨
OOP의 한계? 부족한점? 최소한의 단위로 나누려고 하는데
더 이상 쪼개지지 않는 단위까지 가게됨(클래스 단위의 모듈 - 컴퍼넌트)

예를 들어 은행업무를 모듈 단위로 작성하게 될 때
로그, 트랜잭션, 보안의 코드들이 예금, 보험, 여신 과 같은 모듈에 
중복되어서 작성하게되는데 이를 따로 모듈로 만들어 놓을 수 있다
하지만 따로만든 모듈도 결론적으로 각각의 모듈에서 쓰이기 된다
이러한 중복되는 코드들을 극복하게 해주는 것이 AOP이다



AOP는 중복되는 특정 기능을 코드에 작성하지 않고
필요한 시점에 알아서 실행이 되도록 해준다
이는 AOP의 인터셉터 기능을 통해서 해줌


AOP - 횡단관심사, 종단관심사

1) 정의
          기능을 핵심 비지니스 로직과 공통 모듈로 구분하고,
          핵심 로직에 영향을 미치지 않고 사이사이에 공통모듈을 효과적으로
          잘 끼워 넣도록 하는 개발 방법

2) 용도
          ㄱ) 간단한 메서드 성능 검사
          ㄴ) 트랜젝션 처리
          ㄷ) 예외처리 반환
          ㄹ) 아키텍쳐 검증
          ㅁ) 기타...(로깅, 인증, 권한 등등)

3) 구성요소
          a) JoinPoint - 코드가 삽입될 실제 위치
          b) Pointcut - 같은 기능의 JoinPoint의 묶음(예)로그 JoinPoint, 보안 JoinPoint ...
          c) Advice - 기능 구현을 위해 만든 코드
          d) Advisor - Pointcut + Advice 두개를 쉽게 관리할 수 있게 하는 단위
          e) Weaving - 행동대장, Advisor를 필요할 때 끼워넣는 행위
                     -> Weaving을 당하는 대상을 Target Class 라고 한다



----------------------------------- 
###################################
2. 설정 및 그 밖에
-----------------------------------
* 패키지 만듬 - /basic/src/main/java/basic08 
/basic02 패키지 내용을 전부 복사 해옴
----------------------------------- 
* xml 만듬


beans는 기본값으로 선택을 안해도 선택이 된다


Finish

만약 만들어진 내용 중에 Namespace추가하고 싶으면




----------------------------------- 

* 패키지 생성 - /basic/src/main/java/basic09
basic08의 설정파일(xml)을 제외한 내용 복사
basic06의 FileOutputter.java, Outputter.java 복사
----------------------------------- 
* 패키지 생성 - /basic/src/main/java/basic10
basic09의 설정 클래스를 제외한 내용 복사
----------------------------------- 
* java에서 필요한 어노테이션 라이브러리가 필요함
/basic/src/main/java/basic10/MessageBeanImpl.java
에서 @Resource를 쓸 때 아래 주소의 maven 사용
http://mvnrepository.com/artifact/javax.annotation/jsr250-api/1.0
-----------------------------------
###################################
3. 소스코드 또는 실습 
-----------------------------------
3-1
Workspace : ~\study\SpringWork 
Content : Bean Life Cycle 
/basic/src/main/java/basic07/CustomBeanPostProcessor.java

package basic07;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class CustomBeanPostProcessor implements BeanPostProcessor {

     public Object postProcessAfterInitialization(Object arg0, String arg1) 
               throws BeansException {
          System.out.println("8. 초기화 후 빈에 대한 처리 설정" 
               + arg0.toString() + ", " + arg1.toString());
          // null이 리턴 되면 라이프사이클이 끝남
          return arg0;
     }

     public Object postProcessBeforeInitialization(Object arg0, String arg1) 
               throws BeansException {
          System.out.println("5. 초기화 전 빈에 대한 처리 설정" 
               + arg0.toString() + ", " + arg1.toString());
          // null이 리턴 되면 라이프사이클이 끝남
          return arg0;
     }

}
----------------------------------- 
3-2
Workspace : ~\study\SpringWork
Content : Bean Life Cycle
/basic/src/main/java/basic07/App.java

package basic07;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class App {
     public static void main(String[] args) {
          // DefaultListableBeanFactory에 메서드로 라이프사이클에 넣기 위해서
          // 전에는 BeanFactory로 만들었으나 부모 클래스로 받음
          // BeanFactory factory = new DefaultListableBeanFactory();
          // DefaultListableBeanFactory factory = new
          // DefaultListableBeanFactory();
          //
          // new XmlBeanDefinitionReader(((BeanDefinitionRegistry) factory))
          // .loadBeanDefinitions(new FileSystemResource("basic07_config.xml"));

          // 라이프사이클에 동참시키기 위해서 넣음
          // factory.addBeanPostProcessor(new CustomBeanPostProcessor());
          // 위 코드를 XML에서 생성하는 방법? DI를 적용시키기 위해
          // 인스턴스 생성은 XML에서 할 수 있지만 DefaultListableBeanFactory에서 가져올 수 없음

          // 하지만 XML에서 생성된 것을 가져다 쓸 수 있는 클래스가 있음
          ApplicationContext factory = new FileSystemXmlApplicationContext("basic07_config.xml");          

          MessageBean bean = factory.getBean("msgKr", basic07.MessageBean.class);
          bean.sayHello();
     }
}
----------------------------------- 
3-3
Workspace : ~\study\SpringWork
Content : Bean Life Cycle
/basic/basic07_config.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.xsd">

     <bean id="msgKr" class="basic07.MessageBeanImpl" init-method="init">
          <constructor-arg value="홍길동"></constructor-arg>
          <constructor-arg value="40"></constructor-arg>
          <constructor-arg value="새해 복 많이 받으세요"></constructor-arg>
          <property name="greeting">
               <value>안녕하십니까</value>               
          </property>                    
     </bean>
     
     <bean id="beanPostProcess" class="basic07.CustomBeanPostProcessor"/>
</beans>
----------------------------------- 
3-4
Workspace : ~\study\SpringWork
Content : Bean 생성 방법
/basic/src/main/java/basic08/basic08_config.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"
     xmlns:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
          http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">
     
<!--      <bean id="msgKr" class="basic08.MessageBeanImpl"> -->
<!--           <property name="name" value="홍길동" /> -->
<!--           <property name="age" value="20" /> -->
<!--      </bean> -->
<!--      <bean id="msgEn" class="basic08.MessageBeanImplEn"> -->
<!--           <property name="name" value="Tom" /> -->
<!--           <property name="age" value="21" /> -->
<!--      </bean> -->

          <context:component-scan base-package="basic08"></context:component-scan>
</beans>
----------------------------------- 
3-5 
Workspace : ~\study\SpringWork
Content : Bean 생성 방법
/basic/src/main/java/basic08/MessageBean.java

package basic08;

public interface MessageBean {
     public void sayHello();
}
----------------------------------- 
3-6
Workspace : ~\study\SpringWork
Content : Bean 생성 방법
/basic/src/main/java/basic08/MessageBeanImpl.java

package basic08;

import org.springframework.stereotype.Component;

@Component
public class MessageBeanImpl implements MessageBean {
     private String name;
     private int age;

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getAge() {
          return age;
     }

     public void setAge(int age) {
          this.age = age;
     }

     @Override
     public void sayHello() {
          System.out.println("안녕하세요~~~" + name + "(" + age + ")님!");
     }
}
----------------------------------- 
3-7 
Workspace : ~\study\SpringWork
Content : Bean 생성 방법
/basic/src/main/java/basic08/MessageBeanImplEn.java

package basic08;

import org.springframework.stereotype.Component;

@Component("msgEn")
public class MessageBeanImplEn implements MessageBean{
     private String name;
     private int age;

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getAge() {
          return age;
     }

     public void setAge(int age) {
          this.age = age;
     }

     @Override
     public void sayHello() {
          System.out.println("Hello~~~" + name + "(" + age + ")님!");
     }
}
----------------------------------- 
3-8 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic09/App.java

package basic09;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {
     public static void main(String[] args) {
          // 파일로 부터 읽어드리는 클래스를 사용
          ApplicationContext factory = new
          AnnotationConfigApplicationContext(ApplicationContextConfigure.class);

          MessageBean bean = factory.getBean("getMessageKr", basic09.MessageBean.class);
          bean.sayHello();

          bean = factory.getBean("getMessageEn", basic09.MessageBean.class);
          bean.sayHello();
     }
}
----------------------------------- 
3-9 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic09/ApplicationContextConfigure.java

package basic09;

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

@Configuration
public class ApplicationContextConfigure {
     @Bean
     public MessageBean getMessageKr(){
          MessageBeanImpl bean = new MessageBeanImpl();
          bean.setName("홍길동");
          bean.setAge(25);
          bean.setOutputter(getOutput());
          return bean;
     }
     
     @Bean
     public MessageBean getMessageEn(){
          MessageBeanImplEn bean = new MessageBeanImplEn();
          bean.setName("Johnson");
          bean.setAge(30);
          bean.setOutputter(getOutput());
          return bean;
     }
     
     @Bean
     public Outputter getOutput(){
          return new FileOutputter();
     }
}

----------------------------------- 
3-10 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic09/MessageBeanImpl.java

package basic09;

public class MessageBeanImpl implements MessageBean {
     private String name;
     private int age;
     private Outputter outputter;

     public Outputter getOutputter() {
          return outputter;
     }

     public void setOutputter(Outputter outputter) {
          this.outputter = outputter;
     }

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getAge() {
          return age;
     }

     public void setAge(int age) {
          this.age = age;
     }

     @Override
     public void sayHello() {
          System.out.println("안녕하세요~~~" + name + "(" + age + ")님!");
          System.out.println("한글 : "+outputter.toString());
     }
}
----------------------------------- 
3-11 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic09/MessageBeanImplEn.java

package basic09;

public class MessageBeanImplEn implements MessageBean{
     private String name;
     private int age;
     private Outputter outputter;

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getAge() {
          return age;
     }

     public void setAge(int age) {
          this.age = age;
     }
     
     public void setOutputter(Outputter outputter) {
          this.outputter = outputter;
     }

     @Override
     public void sayHello() {
          System.out.println("Hello~~~" + name + "(" + age + ")님!");
          System.out.println("English : "+outputter.toString());
     }
}
----------------------------------- 
3-12 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic10/App.java

package basic10;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class App {
     public static void main(String[] args) {
          // 파일로 부터 읽어드리는 클래스를 사용
          ApplicationContext factory = 
                    new FileSystemXmlApplicationContext("classpath:/basic10/basic10_config.xml");

          MessageBean bean = factory.getBean("msgKr", basic10.MessageBean.class);
          bean.sayHello();
     }
}
----------------------------------- 
3-13 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic10/MessageBeanImpl.java

package basic10;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;

public class MessageBeanImpl implements MessageBean {
     private String name;
     private int age;
     
     @Autowired
     private Outputter outputter;

     public Outputter getOutputter() {
          return outputter;
     }
     
//     @Autowired
//     public void setOutputter1(Outputter outputter) {
//          this.outputter = outputter;
//     }
     
//     public void setOutputter1(Outputter outputter) {
//          this.outputter = outputter;
//     }

     public String getName() {
          return name;
     }

     public void setName(String name) {
          this.name = name;
     }

     public int getAge() {
          return age;
     }

     public void setAge(int age) {
          this.age = age;
     }

     public void sayHello() {
          System.out.println("안녕하세요~~~" + name + "(" + age + ")님!");
          try{
               outputter.output("10번째 예제입니다-10.");
          }catch(Exception e){e.getStackTrace();}
     }
}
----------------------------------- 
3-14 
Workspace : ~\study\SpringWork
/basic/src/main/java/basic10/basic10_config.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:context="http://www.springframework.org/schema/context"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
     <context:component-scan base-package="basic10" />
     <bean id="msgKr" class="basic10.MessageBeanImpl">
          <property name="name">
               <value>홍길동</value>
          </property>
          
          <property name="age" value="20"/>
          
<!--           <property name="outputter"> -->
<!--                <ref bean="outputter"/>     -->
<!--           </property> -->
     </bean>

     <bean id="outputter" class="basic10.FileOutputter">
          <property name="filePath" value="d:\out10.txt"></property>
     </bean>
</beans>
----------------------------------- 
3-15 
Workspace : ~\study\SpringWork
/basic/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>com.study.myproject</groupId>
     <artifactId>basic</artifactId>
     <version>0.0.1-SNAPSHOT</version>
     <packaging>jar</packaging>

     <name>basic</name>
     <url>http://maven.apache.org</url>

     <properties>
          <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>

     <dependencies>
          <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>3.8.1</version>
               <scope>test</scope>
          </dependency>
          <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-context</artifactId>
               <version>4.1.7.RELEASE</version>
          </dependency>
          <dependency>
               <groupId>javax.annotation</groupId>
               <artifactId>jsr250-api</artifactId>
               <version>1.0</version>
          </dependency>
     </dependencies>
</project>
----------------------------------- 
###################################
4. 과제
-----------------------------------
4-1
/basic/src/main/java/basic10 에서 
코드를 많이 수정하면서 테스트를 하였음 
이 부분 확인 필요
----------------------------------- 
###################################
5. 과제 해결
-----------------------------------
-----------------------------------
###################################
6. 기타
----------------------------------- 
----------------------------------- 

'OpenFrameWork' 카테고리의 다른 글

오픈프레임워크_Day87  (0) 2015.07.16
오픈프레임워크_Day86  (0) 2015.07.16
오픈프레임워크_Day84  (0) 2015.07.13
오픈프레임워크_Day83  (0) 2015.07.10
오픈프레임워크_Day82  (0) 2015.07.09
,