1. DI (Dependency Injection, 의존 주입)
2. AOP (Aspect Oriented Programming, 관점 지향 프로그래밍)
3. IoC (Inversion of Control,제어의 역전)
제어의 역전은 의존성 주입의 상위 개념
스프링 컨테이너가 필요에 따라 개발자 대신 Bean들을 관리(제어)해주는 행위
TDD (Test Driven Development, 테스트 주도 개발)
- 테스트 프로그램을 만드는 것
- 코드는 볼 수 없다
- 즉 프로그래머와 테스터는 분리된다.
주입 방식
생성자 주입
필드 주입 (@Autowired)
setter 주입
setter @Autowired 주입
//1. 스프링 없이 주입시키는 방법
// - 생성자 주입
class Apple{
void f1() { System.out.println("test"); }
}
class Orange{
Apple apple;
Orange(Apple apple){
this.apple = apple;
}
void f2() {
apple.f1();
}
}
public class Hello {
public static void main(String[] args) {
Orange orange = new Orange(new Apple());
orange.f2();
}
}
//2. 스프링 없이 주입시키는 방법
//- setter 주입
class Apple{
void f1() { System.out.println("test"); }
}
class Orange{
Apple apple;
void setApple(Apple apple) {
this.apple = apple;
}
void f2() {
apple.f1();
}
}
public class Hello {
public static void main(String[] args) {
Orange orange = new Orange();
orange.setApple(new Apple());
orange.f2();
}
}
package Pack;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
Apple apple;
Orange(Apple apple){
this.apple = apple;
}
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
//Bean객체의 이름을 변경할 수 있다
//@Bean(name="appleMange")
@Bean
Apple apple() {
return new Apple();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
//얘네들이 관리하는 객체의 수
System.out.println(ctx.getBeanDefinitionCount());
Orange orange = new Orange(new Apple());
orange.f2();
ctx.close();
}
}
package Pack;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
Apple apple;
//생성자 주입
Orange(Apple apple){
this.apple = apple;
}
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
//Bean객체의 이름을 변경할 수 있다
//@Bean(name="appleMange")
@Bean
Apple apple() {
return new Apple();
}
//결국 apple은 싱글톤으로 같은 객체이다
@Bean
Orange orange() {
return new Orange(apple());
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
// //얘네들이 관리하는 객체의 수
// System.out.println(ctx.getBeanDefinitionCount());
// Orange orange = new Orange(new Apple());
// orange.f2();
//
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
- 사용하지 말라고 권장된다. - 스프링 제작진
- 서로 호출하면서 의존관계에 빠진다라는 주장
- 하지만 어차피 처음부터 이렇게 짜면 안된다.
- 실전에서 사용을 많이 한다.
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
@Autowired //아래와 동일한 생성자코드를 만들어준다. + 아래의 Orange(apple())
Apple apple;
// Orange(Apple apple){
// this.apple = apple;
// }
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
//Bean객체의 이름을 변경할 수 있다
//@Bean(name="appleMange")
@Bean
Apple apple() {
return new Apple();
}
//결국 apple은 싱글톤으로 같은 객체이다
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
// //얘네들이 관리하는 객체의 수
// System.out.println(ctx.getBeanDefinitionCount());
// Orange orange = new Orange(new Apple());
// orange.f2();
//
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
객체 수가 많을 때는 보이기 위해 주로 setter함수를 사용
- 객체가 적으면 생성자 주입을 주로 사용
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
Apple apple;
//setter 주입 - 수정자 주입
void setApple(Apple apple) {
this.apple = apple;
}
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
// //결국 apple은 싱글톤으로 같은 객체이다
// @Bean
// Orange orange() {
// return new Orange();
// }
//spring용 setter 주입
@Bean
Orange orange() {
Orange o = new Orange();
o.setApple(apple());
return o;
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
// //setter 주입
// Orange o = new Orange();
// o.setApple(new Apple());
// o.f2();
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
Apple apple;
//setter 주입 - 수정자 주입
@Autowired
void setApple(Apple apple) {
this.apple = apple;
}
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
// //결국 apple은 싱글톤으로 같은 객체이다
// @Bean
// Orange orange() {
// return new Orange();
// }
//spring용 setter 주입
@Bean
Orange orange() {
// Orange o = new Orange();
// o.setApple(apple());
// return o;
//@Autowired 사용할 시 이렇게만
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
// //setter 주입
// Orange o = new Orange();
// o.setApple(new Apple());
// o.f2();
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
class Apple{
void f1() {
System.out.println("test");
}
}
class Orange{
//한번만 받도록
//한 번 주입이 일어나면 이후는 불변의 원칙
final Apple apple;
Orange(Apple apple){
this.apple = apple;
}
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange(apple());
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
객체가 없을 때, @Nullable은 setter 함수 호출은 시켜준 다음 터진다.
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
Apple apple;
@Autowired
//void setApple(Apple apple) {
//Apple 객체가 없을 때, @Nullable은 호출은 시켜준다음 터진다
void setApple(@Nullable Apple apple) {
System.out.println("호출");
//@Nullable이 있기에 제어코드 작성이 가능해진다.
if(apple != null) {
this.apple = apple;
}
}
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
// @Bean
// Apple apple() {
// return new Apple();
// }
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
Apple apple;
@Autowired
//void setApple(Apple apple) {
//Apple 객체가 없을 때, @Nullable은 호출은 시켜준다음 터진다
void setApple(@Nullable Apple apple) {
System.out.println("호출");
//@Nullable이 있기에 제어코드 작성이 가능해진다.
if(apple != null) {
this.apple = apple;
}
}
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
Apple apple;
@Autowired
//void setApple(Apple apple) {
//Apple 객체가 없을 때, @Nullable은 호출은 시켜준다음 터진다
//void setApple(@Nullable Apple apple) {
void setApple(Optional<Apple> apple) {
if(apple.isPresent()) {
System.out.println("객체가 존재하는 경우");
this.apple = apple.get();
}else {
System.out.println("객체가 존재하지 않는 경우");
}
System.out.println("호랑이");
}
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
// @Bean
// Apple apple() {
// return new Apple();
// }
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
Apple apple;
@Autowired
//void setApple(Apple apple) {
//Apple 객체가 없을 때, @Nullable은 호출은 시켜준다음 터진다
//void setApple(@Nullable Apple apple) {
void setApple(Optional<Apple> apple) {
if(apple.isPresent()) {
System.out.println("객체가 존재하는 경우");
this.apple = apple.get();
}else {
System.out.println("객체가 존재하지 않는 경우");
}
System.out.println("호랑이");
}
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
객체 생성자가 2개가 있는 경우
싱글톤에서는 문제가 발생하지 않는다.
하지만, AutoWired 잡으면 누구를 적용시켜야할지 모른다.
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
@Autowired
Apple apple;
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
@Bean
Apple apple01() {
return new Apple();
}
@Bean
Apple apple02() {
return new Apple();
}
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
한정자: 사용 범위를 조건이나 제한을 걸 때 사용되는 예약어
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("----헤드라인----");
}
}
class Orange{
@Autowired
Apple apple;
void f2() {
if(apple != null) {
apple.f1();
}
System.out.println("대선 D-1");
}
}
@Configuration
class AppConfig{
@Bean
@Qualifier("apple01")
Apple apple01() {
return new Apple();
}
@Bean
@Qualifier("apple02")
Apple apple02() {
return new Apple();
}
//spring용 setter 주입
@Bean
Orange orange() {
return new Orange();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Orange orange = ctx.getBean("orange", Orange.class);
orange.f2();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("사과");
}
}
class Orange extends Apple{
@Override
void f1() {
System.out.println("오렌지");
}
}
class Kiwi{
Apple a1 = new Apple();
Apple a2 = new Orange();
@Autowired
Apple apple; //Apple //Orange
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
@Bean
Orange orange() {
return new Orange();
}
@Bean
Kiwi kiwi() {
return new Kiwi();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Kiwi kiwi = ctx.getBean("kiwi", Kiwi.class);
kiwi.f2();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
class Apple{
void f1() {
System.out.println("사과");
}
}
class Orange extends Apple{
@Override
void f1() {
System.out.println("오렌지");
}
}
class Kiwi{
Apple a1 = new Apple();
Apple a2 = new Orange();
@Autowired
@Qualifier("orange")
Apple apple; //Apple //Orange
void f2() {
apple.f1();
}
}
@Configuration
class AppConfig{
@Bean
Apple apple() {
return new Apple();
}
@Bean
Orange orange() {
return new Orange();
}
@Bean
Kiwi kiwi() {
return new Kiwi();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Kiwi kiwi = ctx.getBean("kiwi", Kiwi.class);
kiwi.f2();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
Airplane(Water water){
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
}
public class Hello {
public static void main(String[] args) {
Airplane airplane = new Airplane(new Water());
airplane.fly();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
Airplane(Water water){
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
@Bean
Water water() {
return new Water();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Water water = ctx.getBean("water", Water.class);
Airplane airplane = new Airplane(water);
airplane.fly();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
Airplane(Water water){
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
@Bean
Water water() {
return new Water();
}
@Bean
Airplane airplane() {
return new Airplane(water());
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
//Water water = ctx.getBean("water", Water.class);
Airplane airplane = ctx.getBean("airplane", Airplane.class);
airplane.fly();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
@Autowired
Water water;
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
@Bean
Water water() {
return new Water();
}
@Bean
Airplane airplane() {
return new Airplane(water());
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Airplane airplane = ctx.getBean("airplane", Airplane.class);
airplane.fly();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
@Autowired
void setWater(Water water) {
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
@Bean
Water water() {
return new Water();
}
@Bean
Airplane airplane() {
return new Airplane();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Airplane airplane = ctx.getBean("airplane", Airplane.class);
airplane.fly();
ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
@Autowired
void setWater(Water water) {
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
class AppConfig{
@Bean
Water water() {
return new Water();
}
// @Bean
// Airplane airplane() {
// return new Airplane();
// }
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Airplane airplane = ctx.getBean("airplane", Airplane.class);
airplane.fly();
ctx.close();
}
}
객체가 없는 경우 자동적으로 생성시켜버린다.
@ComponentScan
스프링 3.1부터 도입된 Annotation이며 스캔 위치를 설정하고,
어떤 Annotation을 스캔할지 또는 하지 않을지 결정하는 Filter 기능을 가지고있다.
@Component
컴포넌트 스캔이 스캐닝하는 기준
@Component를 들고있는 클래스들이 스캐닝되고, Bean으로 등록된다.
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
@Component
//의존 관계 (Airplane-Water)
class Airplane{
Water water;
@Autowired
void setWater(Water water) {
this.water = water;
}
void fly() {
this.water.use();
System.out.print(" 날아간다.");
}
}
class Water{
void use() {
System.out.print("물을 사용해서");
}
}
@Configuration
@ComponentScan
class AppConfig{
@Bean
Water water() {
return new Water();
}
}
public class Hello {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppConfig.class);
Airplane airplane = ctx.getBean("airplane", Airplane.class);
airplane.fly();
ctx.close();
}
}
스프링 컨테이너는 다양한 형식의 설정 정보(Config)를 받을 수 있다.
ex) 자바코드, XML, Groovy 등
- 권장사항: 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">
</beans>
<button></button>
//컴파일시
Button button = new Button();
DAO (Data Access Object), DTO(Data Transfer Object), VO(Value Object), Entity
클래스 구성
Member: Entity 클래스의 역할
MemberDao: CRUD 담당
CRUD는 CRUD만 해야한다. 즉 다른 예외처리 등을 해서는 안된다.
RegisterRequest: VO 클래스의 역할
MemberRegisterService: MemberDao를 서포트해주는 역할
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
this.name = name;
}
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
String inputName = "홍길동";
RegisterRequest rr = new RegisterRequest(inputName);
// GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:Context.xml");
// ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
String inputName = "홍길동";
RegisterRequest rr = new RegisterRequest(inputName);
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
//member -> DB에 저장(Map Collection 사용)
// GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:Context.xml");
// ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
//DAO class
class MemberDao{
void insert(Member member) {
//쿼리 문장을 사용하는 코드이지만
System.out.println(member.name + "DB에 저장하였습니다.");
}
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
String inputName = "홍길동";
RegisterRequest rr = new RegisterRequest(inputName);
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
//member -> DB에 저장(Map Collection 사용)
MemberDao memberDao = new MemberDao();
memberDao.insert(member);
// GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:Context.xml");
// ctx.close();
}
}
Dao와의 차이점은 리턴값을 받아서 어떠한 판단을하게 된다.
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
//DAO class
class MemberDao{
void insert(Member member) {
//쿼리 문장을 사용하는 코드이지만
System.out.println(member.name + "DB에 저장하였습니다.");
}
}
class MemberRegisterService{
MemberDao memberDao;
MemberRegisterService(MemberDao memberDao){
this.memberDao = memberDao;
}
void register(Member member) {
memberDao.insert(member);
}
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
String inputName = "홍길동";
RegisterRequest rr = new RegisterRequest(inputName);
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
MemberRegisterService mrs = new MemberRegisterService(new MemberDao());
//member -> DB에 저장(Map Collection 사용)
MemberDao memberDao = new MemberDao();
memberDao.insert(member);
// GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:Context.xml");
// ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
//DAO class
class MemberDao{
boolean insert(Member member) {
//쿼리 문장을 사용하는 코드이지만
System.out.println(member.name + "DB에 저장하였습니다.");
return true;
}
}
class MemberRegisterService{
MemberDao memberDao;
public MemberRegisterService(MemberDao memberDao){
this.memberDao = memberDao;
}
void register(RegisterRequest rr) {
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
if(memberDao.insert(member) == true) {
System.out.println("모든 작업이 정상입니다.");
}
}
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
String inputName = "홍길동";
RegisterRequest rr = new RegisterRequest(inputName);
MemberRegisterService mrs = new MemberRegisterService(new MemberDao());
mrs.register(rr);
//member -> DB에 저장(Map Collection 사용)
// MemberDao memberDao = new MemberDao();
// memberDao.insert(rr);
// GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:Context.xml");
// ctx.close();
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
//DAO class
class MemberDao{
boolean insert(Member member) {
//쿼리 문장을 사용하는 코드이지만
System.out.println(member.name + "DB에 저장하였습니다.");
return true;
}
}
class MemberRegisterService{
@Autowired
MemberDao memberDao;
// public MemberRegisterService(MemberDao memberDao){
// this.memberDao = memberDao;
// }
//
void register(RegisterRequest rr) {
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
if(memberDao.insert(member) == true) {
System.out.println("모든 작업이 정상입니다.");
}
}
}
@Configuration
class AppConfig{
@Bean
MemberDao memberDao() {
return new MemberDao();
}
@Bean
MemberRegisterService memberRegisterService() {
//return new MemberRegisterService(memberDao());
return new MemberRegisterService();
}
}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
// String inputName = "홍길동";
// RegisterRequest rr = new RegisterRequest(inputName);
//
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
MemberRegisterService mrs = ctx.getBean("memberRegisterService", MemberRegisterService.class);
mrs.register(new RegisterRequest("홍길동"));
ctx.close();
// MemberRegisterService mrs = new MemberRegisterService(new MemberDao());
// mrs.register(rr);
//member -> DB에 저장(Map Collection 사용)
// MemberDao memberDao = new MemberDao();
// memberDao.insert(rr);
}
}
package Pack;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericXmlApplicationContext;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
class FormDTO{
String name;
FormDTO(){
}
}
//VO class
class RegisterRequest{
String name;
RegisterRequest(String name){
//데이터 검증 코드가 상당부분 생략되었다.
this.name = name + "독수리"; //가공
}
}
//Entity class
//class Entity{
// int id;
//}
//class Member extends Entity{
class Member{
int id;
String name;
}
//DAO class
class MemberDao{
boolean insert(Member member) {
//쿼리 문장을 사용하는 코드이지만
System.out.println(member.name + "DB에 저장하였습니다.");
return true;
}
}
class MemberRegisterService{
MemberRegisterService(MemberDao memberDao){
this.memberDao = memberDao;
}
MemberDao memberDao;
// public MemberRegisterService(MemberDao memberDao){
// this.memberDao = memberDao;
// }
//
void register(RegisterRequest rr) {
//Entitiy에 정보 입력
Member member = new Member();
member.id = 1000;
member.name = rr.name;
if(memberDao.insert(member) == true) {
System.out.println("모든 작업이 정상입니다.");
}
}
}
//config
class Assemble{
MemberRegisterService f1() {
MemberRegisterService mrs = new MemberRegisterService(new MemberDao());
mrs.register(new RegisterRequest("홍길동"));
return mrs;
}
}
//@Configuration
//class AppConfig{
// @Bean
// MemberDao memberDao() {
// return new MemberDao();
// }
// @Bean
// MemberRegisterService memberRegisterService() {
// //return new MemberRegisterService(memberDao());
// return new MemberRegisterService(new MemberDao());
// }
//
//}
public class Hello {
public static void main(String[] args) {
//1. 클라이언트에서 데이터를 전송
//2. 서버에서는 DTO 클래스로 값을 얻게 된다.
//3. String name = DTO객체.name;
//4. 키보드에서 input을 받는다. (input이 DTO 데이터이다.)
Assemble a = new Assemble();
MemberRegisterService msr = a.f1();
msr.register(new RegisterRequest("홍길동"));
// String inputName = "홍길동";
// RegisterRequest rr = new RegisterRequest(inputName);
// MemberRegisterService mrs = new MemberRegisterService(new MemberDao());
// mrs.register(rr);
//
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// MemberRegisterService mrs = ctx.getBean("memberRegisterService", MemberRegisterService.class);
// mrs.register(new RegisterRequest("홍길동"));
// ctx.close();
//member -> DB에 저장(Map Collection 사용)
// MemberDao memberDao = new MemberDao();
// memberDao.insert(rr);
}
}
이제는 선택
- CRUD를 클래스로 분리시키기
- 현재코드에 구현하기