★★★★★★스프링의 핵심개념★★★★★★
객체 사이의 의존 관계를 자기 자신이 아닌 외부에 의해서 설정된 개념
Constructor Injectoin
생성자를 통해서 의존 관계를 연결
<constructor-arg>
를 추가해주어야 함
Setter Injection
: setter메소드를 이용하여 의존 관계를 연결시키는 것을 말한다.
: <property>
요소의 name 속성을 이용하여 값의 의존 관계를 연결시킬 대상이 되는 필드값을 지정한다
기본데이터 타입일 경우에는 value 요소를 사용하여 의존관계를 연결시키기 위한 값을 지정
public class Foo {
private int a, b;
public void setA(int a) { }
public void setB(String b) { }
}
[applicationContext.xml]
<bean id="foo" class="Foo">
<property name="a">
<value>25</value>
</property>
<property name="b" value="Hello" />
</bean>
public class Foo {
private Bar bar;
public void setBar(Bar bar){
this.bar = bar;
}
}
public class Bar { }
[applicationContext.xml]
<bean id="foo" class="Foo">
<property name="bar" ref="bar"></property>
</bean>
<bean id="bar" class="Bar" />
---------------------------------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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>chapter02_XML</groupId>
<artifactId>chapter02_XML</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>17</release>
</configuration>
</plugin>
</plugins>
</build>
<!-- Spring Context -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
<!-- Project Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
---------------------------------ApplicationContext.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.3.xsd">
<bean id="messageBeanImpl" class="sample01.MessageBeanImpl">
<constructor-arg>
<value>사과</value>
</constructor-arg>
<property name="cost">
<value>5000</value>
</property>
<property name="qty" value="3"></property>
</bean>
</beans>
---------------------------------MessageBean.interface---------------------------------
package sample01;
public interface MessageBean {
public void sayHello();
public void sayHello(String fruit, int cost);
public void sayHello(String fruit, int cost, int qty);
}
---------------------------------MessageBeanImpl.java---------------------------------
package sample01;
public class MessageBeanImpl implements MessageBean {
private String fruit; /* 기본생성자 */
private int cost; /* setter */
private int qty; /* setter */
/* fruit 기본생성자 */
public MessageBeanImpl(String fruit) {
super(); /* 부모생성자 */
this.fruit = fruit;
}
/* cost setter */
public void setCost(int cost) {
this.cost = cost;
}
/* qty setter */
public void setQty(int qty) {
this.qty = qty;
}
@Override
public void sayHello() {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost, int qty) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
}
---------------------------------HelloSpring.java---------------------------------
package sample01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
MessageBean messageBean = applicationContext.getBean("messageBeanImpl", MessageBean.class);
messageBean.sayHello();
messageBean.sayHello("바나나", 2500);
messageBean.sayHello("참외", 10000, 2);
}
}
xml에서 설정한 값을 나중에 설정한 값이 덮어 씌어주어서 값이 이와 같이 나옴
---------------------------------ApplicationContext.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.3.xsd">
<context:component-scan base-package="sample01"></context:component-scan>
</beans>
---------------------------------MessageBeanImpl.java---------------------------------
package sample01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class MessageBeanImpl implements MessageBean {
private String fruit; /* 기본생성자 */
private int cost; /* setter */
private int qty; /* setter */
/* Constructor Injection */
/* fruit 기본생성자 */
public MessageBeanImpl(@Value("사과") String fruit) {
super(); /* 부모생성자 */
this.fruit = fruit;
}
/* Setter Injection */
/* cost setter */
@Autowired /* setter는 자동으로 데이터를 주는 애가 아니여서 왼쪽과 같은 어노테이션을 줌 */
public void setCost(@Value("5000") int cost) {
this.cost = cost;
}
/* qty setter */
@Autowired
public void setQty(@Value("3") int qty) {
this.qty = qty;
}
@Override
public void sayHello() {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost, int qty) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
}
---------------------------------HelloSpring.java---------------------------------
package sample01;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
MessageBean messageBean = applicationContext.getBean("messageBeanImpl", MessageBean.class);
messageBean.sayHello();
messageBean.sayHello("바나나", 2500);
messageBean.sayHello("참외", 10000, 2);
}
}
@Bean은
---------------------------------MessageBeanImpl.java---------------------------------
package sample01;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//@Component //bean생성하렴~(객체생성ㄱㄱ)
public class MessageBeanImpl implements MessageBean {
private String fruit;
private int cost;
private int qty;
//Constructor Injection
public MessageBeanImpl(@Value("사과")String fruit) {
super(); //부모님모시고와~
this.fruit = fruit;
}
//Setter Injection
@Autowired //요걸 써줘야 호출이됨(자동임)
public void setCost(@Value("5000")int cost) {
this.cost = cost;
}
@Autowired
public void setQty(@Value("3")int qty) {
this.qty = qty;
}
@Override
public void sayHello() {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost, int qty) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
}
---------------------------------SpringConfiguration.java---------------------------------
package spring.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import sample01.MessageBeanImpl;
@Configuration // 스프링 설정파일로 쓰려고 만듬 - bean을 설정할 수 있는
public class SpringConfiguration {
// 빈 생성 - 빈이라고 알려줘야지 spring과 연결이됨
/*
* @Bean
* public MessageBeanImpl messageBeanImpl(){
* return new MessageBeanImpl("사과");
* }
*/
@Bean(name="messageBeanImpl")
public MessageBeanImpl getMessageBeanImpl(){
return new MessageBeanImpl("사과");
}
}
---------------------------------MessageBeanImpl.java---------------------------------
package sample01;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
// @Component -> configuration 해야되서 주석걸었음
@RequiredArgsConstructor
public class MessageBeanImpl implements MessageBean {
@NonNull
private String fruit; /* 기본생성자 */
@Setter
private int cost; /* setter */
@Setter
private int qty; /* setter */
/*
* Constructor Injection fruit 기본생성자 public MessageBeanImpl(@Value("사과") String
* fruit) { super(); 부모생성자 this.fruit = fruit;
*
* }
*
* Setter Injection cost setter
*
* @Autowired setter는 자동으로 데이터를 주는 애가 아니여서 왼쪽과 같은 어노테이션을 줌 public void
* setCost(@Value("5000") int cost) { this.cost = cost; }
*
* qty setter
*
* @Autowired public void setQty(@Value("3") int qty) { this.qty = qty; }
*/
@Override
public void sayHello() {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
@Override
public void sayHello(String fruit, int cost, int qty) {
System.out.println(fruit + "\t" + cost + "\t" + qty);
}
}
--------------------------------Calc.interface--------------------------------
package sample02;
public interface Calc {
public void calculate();
}
--------------------------------CalcAdd.java--------------------------------
package sample02;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class CalcAdd implements Calc {
private int x;
private int y;
/*
* public CalcAdd(int x, int y) {
* super();
* this.x = x;
* this.y = y; }
*/
@Override
public void calculate() {
System.out.println(x + " + " + y + " = " + (x + y));
}
}
--------------------------------CalcMul.java--------------------------------
package sample02;
import lombok.Setter;
public class CalcMul implements Calc {
@Setter
private int x,y;
/*
* public void setX(int x) {
* this.x = x; }
*
* public void setY(int y) {
* this.y = y; }
*/
@Override
public void calculate() {
System.out.println(x + " * " + y + " = " + (x*y));
}
}
--------------------------------ApplicationContext.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.3.xsd">
<!-- smaple01
<bean id="messageBeanImpl" class="sample01.MessageBeanImpl">
<constructor-arg>
<value>사과</value>
</constructor-arg>
<property name="cost">
<value>5000</value>
</property>
<property name="qty" value="3"></property>
</bean>
-->
<!-- sample02 -->
<!-- Constructor는 값을 주어야함 -->
<bean id="clacAdd" class="sample02.CalcAdd">
<constructor-arg value="25"/>
<constructor-arg value="36"/>
</bean>
<!-- Setter 요청 할 수 있도록 property -->
<bean id="clacMul" class="sample02.CalcMul">
<property name="x" value="25"/>
<property name="y" value="36"/>
</bean>
</beans>
--------------------------------HelloSpring.java--------------------------------
package sample02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Calc calc ;
calc = applicationContext.getBean("calcAdd", Calc.class);
calc.calculate();
calc = (Calc)applicationContext.getBean("calcMul");
calc.calculate();
}
}
--------------------------------Calc.interface--------------------------------
package sample02;
public interface Calc {
public void calculate();
}
--------------------------------CalcAdd.java--------------------------------
package sample02;
import org.springframework.beans.factory.annotation.Value;
// @Component
public class CalcAdd implements Calc {
private int x;
private int y;
public CalcAdd(@Value("25") int x, @Value("36") int y) {
super(); /* 생성자가 부모 생성자를 부를 때는 무조건 첫째줄 */
System.out.println("CalcAdd의 기본 생성자");
this.x = x;
this.y = y;
}
@Override
public void calculate() {
System.out.println(x + " + " + y + " = " + (x + y));
}
}
--------------------------------CalcMul.java--------------------------------
package sample02;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
// @Component 는 바로 밑에 있는 클래스 생성
public class CalcMul implements Calc {
private int x,y;
public CalcMul() {
System.out.println("CalcMul의 기본 생성자");
}
@Autowired
public void setX(@Value("25") int x) {
this.x = x;
}
@Autowired
public void setY(@Value("36") int y) {
this.y = y;
}
@Override
public void calculate() {
System.out.println(x + " * " + y + " = " + (x*y));
}
}
--------------------------------ApplicationContext.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.3.xsd">
<!--
<bean id="messageBeanImpl" class="sample01.MessageBeanImpl">
<constructor-arg>
<value>사과</value>
</constructor-arg>
<property name="cost">
<value>5000</value>
</property>
<property name="qty" value="3"></property>
</bean>
-->
<context:component-scan base-package="sample01"></context:component-scan>
<context:component-scan base-package="sample02"></context:component-scan>
<context:component-scan base-package="spring.conf"></context:component-scan>
</beans>
--------------------------------SpringConfiguration.java--------------------------------
package spring.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import sample01.MessageBeanImpl;
import sample02.CalcAdd;
import sample02.CalcMul;
@Configuration // 스프링 설정파일로 쓰려고 만듬 - bean을 설정할 수 있는
public class SpringConfiguration {
// 빈 생성 - 빈이라고 알려줘야지 spring과 연결이됨
/*
* @Bean
* public MessageBeanImpl messageBeanImpl(){
* return new MessageBeanImpl("사과");
* }
*/
@Bean(name="messageBeanImpl")
public MessageBeanImpl getMessageBeanImpl(){
return new MessageBeanImpl("사과");
}
@Bean
public CalcAdd calcAdd(){
return new CalcAdd(25, 36);
}
@Bean(name="calcMul")
public CalcMul getcalcMul(){
return new CalcMul();
}
}
--------------------------------HelloSpring.java--------------------------------
package sample02;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Calc calc ;
calc = applicationContext.getBean("calcAdd", Calc.class);
calc.calculate();
calc = (Calc)applicationContext.getBean("calcMul");
calc.calculate();
}
}
--------------------------------SungJuk.interface--------------------------------
package sample03;
public interface SungJuk {
public void calcTot(); //총점 계산
public void calcAvg(); //평균 계산
public void display(); //출력
public void modify(); //수정
}
--------------------------------SungJukDTO.java--------------------------------
package sample03;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SungJukDTO {
private String name;
private int kor;
private int eng;
private int math;
private int tot;
private double avg;
}
--------------------------------ApplicationContext.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.3.xsd">
<!-- sample03 -->
<bean id="sungJukDTO" class="sample03.SungJukDTO">
<property name="name" value="홍길동"/>
<property name="kor" value="97"/>
<property name="eng" value="100"/>
<property name="math" value="95"/>
</bean>
</beans>
<bean id="sungJukImpl" class="sample03.SungJukImpl">
<constructor-arg ref="sungJukDTO"/>
</bean>
--------------------------------SungJukImpl.java--------------------------------
package sample03;
import java.util.Scanner;
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class SungJukImpl implements SungJuk {
private SungJukDTO sungJukDTO; // 필드, 초기화 = null
// public SungJukImpl(SungJukDTO sungJukDTO) {
// super();
// this.sungJukDTO = sungJukDTO;
// }
=> @AllArgsConstructor와 public SungJukImpl 코드 둘중에 하나 써야됨
@Override
public void calcTot() {
sungJukDTO.setTot(sungJukDTO.getKor() + sungJukDTO.getEng() + sungJukDTO.getMath());
}
@Override
public void calcAvg() {
sungJukDTO.setAvg(sungJukDTO.getTot()/3.0);
}
@Override
public void display() {
System.out.println("이름\t국어\t영어\t수학\t총점\t평균");
System.out.println(sungJukDTO);
}
@Override
public void modify() {
Scanner scan = new Scanner(System.in);
System.out.print("이름 입력 : ");
String name = scan.next();
System.out.print("국어 입력 : ");
int kor = scan.nextInt();
System.out.print("영어 입력 : ");
int eng = scan.nextInt();
System.out.print("수학 입력 : ");
int math = scan.nextInt();
System.out.println();
sungJukDTO.setName(name);
sungJukDTO.setKor(kor);
sungJukDTO.setEng(eng);
sungJukDTO.setMath(math);
}
}
--------------------------------HelloSpring.java--------------------------------
package sample03;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpring {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
SungJuk sungJuk = applicationContext.getBean("sungJukImpl", SungJuk.class);
sungJuk.calcTot();
sungJuk.calcAvg();
sungJuk.display();
System.out.println();
sungJuk.modify(); // 수정
sungJuk.calcTot();
sungJuk.calcAvg();
sungJuk.display();
}
}
--------------------------------SungJukDTO.java--------------------------------
package sample03;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class SungJukDTO {
private String name;
private int kor;
private int eng;
private int math;
private int tot;
private double avg;
public String getName() {
return name;
}
@Autowired
public void setName(@Value("홍길동") String name) {
this.name = name;
}
public int getKor() {
return kor;
}
@Autowired
public void setKor(@Value("97") int kor) {
this.kor = kor;
}
public int getEng() {
return eng;
}
@Autowired
public void setEng(@Value("100") int eng) {
this.eng = eng;
}
public int getMath() {
return math;
}
@Autowired
public void setMath(@Value("95") int math) {
this.math = math;
}
public int getTot() {
return tot;
}
public void setTot(int tot) {
this.tot = tot;
}
public double getAvg() {
return avg;
}
public void setAvg(double avg) {
this.avg = avg;
}
@Override
public String toString() {
return name + "\t"+ kor +"\t"+ eng +"\t"+ math +"\t"+ tot +"\t"+ String.format("%.2f", avg) ;
// 이렇게 하면 Impl에서 display()에서처럼 찍을 필요가 없다.
/*
System.out.println("이름"+"\t"+"국어"+"\t"+"영어"+"\t"+"수학"+"\t"+"총점"+"\t"+"평균");
System.out.println(sungJukDTO.getName()+"\t"
+sungJukDTO.getKor()+"\t"
+sungJukDTO.getEng()+"\t"
+sungJukDTO.getMath()+"\t"
+sungJukDTO.getTot()+"\t"
+String.format("%.2f", sungJukDTO.getAvg()));
*/
}
}
--------------------------------ApplicationContext.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.3.xsd">
<context:component-scan base-package="sample03"></context:component-scan>
</beans>
--------------------------------SungJukImpl.java--------------------------------
package sample03;
import java.util.Scanner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class SungJukImpl implements SungJuk {
// @Autowired :
// 생성된 bean들(@component, @Bean) 중에서 SungJukDTO 찾아서 매핑을 해라
// - 생성자던 setter 메소드던 상관없이 매핑을 해라(자동 매칭)
@Autowired
private SungJukDTO sungJukDTO=null; // 필드, 초기화 = null
@Override
public void calcTot() {
sungJukDTO.setTot(sungJukDTO.getKor() + sungJukDTO.getEng() + sungJukDTO.getMath());
}
@Override
public void calcAvg() {
sungJukDTO.setAvg(sungJukDTO.getTot()/3.0);
}
@Override
public void display() {
System.out.println("이름\t국어\t영어\t수학\t총점\t평균");
System.out.println(sungJukDTO);
}
@Override
public void modify() {
Scanner scan = new Scanner(System.in);
System.out.print("이름 입력 : ");
String name = scan.next();
System.out.print("국어 입력 : ");
int kor = scan.nextInt();
System.out.print("영어 입력 : ");
int eng = scan.nextInt();
System.out.print("수학 입력 : ");
int math = scan.nextInt();
System.out.println();
sungJukDTO.setName(name);
sungJukDTO.setKor(kor);
sungJukDTO.setEng(eng);
sungJukDTO.setMath(math);
}
}