pom.xml => 라이브러리 저장
여기저장하면 메이븐 디벤던시스에 자동으로 들어감
프로그램 생성시 에러 발생하는 경우 repository폴더 삭제 후 다시 라이브러리 다운로드 (교재 31-32p)
C:\Users\사용자이름.m2\repository\org
Ajax의 x가 xml의미
완성된 소프트웨어가 아니라 어떤 문제를 해결하기 위해서 만들어진 미완의 모듈로 모든 자바개발자들이 공통으로 사용하는 기능을 미리 만들어서 제공하는 프로그램
=> 해결해야하는 문제 : 내가 개발해야하는 시스템
ex. 교육시스템, 예약시스템, 인터넷뱅킹, 쇼핑몰, 게임사이트...
재사용이 가능한 모듈, 일반적으로 프레임워크를 이용해서 개발하는 시스템들의 공통모듈은 프레임워크에서 제공하는 기능을 이용해서 개발
=> 공통모듈 : db연동, 트랜잭션처리, 뷰관리, 로그기록, 보안, 다국어처리, 메시징, ...
검증받은 프로그램으로 신뢰성이 높은 시스템을 개발할 수 있다.
프레임워크를 이용해서 개발하면 개발자들간의 의사소통이 가능
대부분 개발자들이 직접 개발하고 처리하던 작업을 프레임워크가 제공해주기 때문에 유지보수나 시스템개발을 위해 필요한 시간을 절약할 수 있다.
(프레임워크를 제대로 이해하고 있는 것이 전제로 들어가야함)
경량의 모듈로 개발이 가능
프레임워크에서 제공하는 모듈(XXX.jar - 라이브러리, 기능들)은 누가 언제 어떤 시스템을 개발하더라도 바로 사용할 수 있는 가볍고 안정적인 모듈
=> DI와 DL
=> 제어의 역전
=> 내가 관리하던 객체를 컨테이너에게 위임
즉, 내가 필요한 곳에서 직접 소스 안에서 객체생성을 하지 않고 컨테이너로부터 전달받아서 사용할 수 있도록 처리
=> IoC컨테이너에서 받은 객체(빈 Bean)는 싱글톤으로 관리된다.(기본설정)
[스프링 IoC컨테이너의 종류]
BeanFactory
↑
ApplicationContext
↑
WebApplicationContext
getBean이 호출되면 요청한 객체가 만들어진다.
웹환경에서 사용
=> 대표 컨테이너이므로 인터페이스
=> 이 인터페이스의 하위를 이용해서 작업
스프링 컨테이너 - ApplicationContext, IoC, DI
설정파일에 등록한 객체를 컨테이너가 제공하는 메소드(getBean)를 이용해서 빈을 찾아오는 작업

public abstract class Connection {
String url;
public Connection(String url){
this.url=url;
}
public abstract void connect();
}
public class MongoDBConnection extends Connection {
public MongoDBConnection(String url) {
super(url);
}
public void connect() {
System.out.println(url + "위치의 MongoDB 서버로 연결됐습니다.");
}
}
public class MySQLConnection extends Connection {
public MySQLConnection(String url) {
super(url);
}
public void connect() {
System.out.println(url + "위치의 MySQL 서버로 연결됐습니다.");
}
}
public class OracleConnection extends Connection {
public OracleConnection(String url) {
super(url);
}
public void connect() {
System.out.println(url + "위치의 오라클 서버로 연결됐습니다.");
}
}
객체생성만 담당하는 클래스(외부조립기, 컨테이너(객체라이프사이클담당))
public class ConnectionFactory {
public Connection getConnection(String str) {
String url = str.toLowerCase();//넘어오는거 소문자로 변경
//지금은 if문을 이용해서 객체를 가져오지만 자동으로 객체가 만들어질 수 있도록
//properties파일, xml에 객체를 등록하면
//시작될때 파일에 등록된 객체를 자동으로 만들고 시작하도록 구현
if (url.indexOf("oracle") >= 0) {
return new OracleConnection(url);//객체생성?
} else if (url.indexOf("mysql") >= 0) {
return new MySQLConnection(url);
} else if (url.indexOf("mongo") >= 0) {
return new MongoDBConnection(url);
} else {
return null;
}
if~else문으로 구현한건 할수없이..
}
}


public interface MyBeanStyle {
void testHello(String name);
}
public class MyBeanStyleA implements MyBeanStyle{
public MyBeanStyleA() {
System.out.println("기본생성자 - MyBeanStyleA");
}
public void testHello(String name) {
System.out.println("hello.."+name+"!");
}
}
public class MyBeanStyleB implements MyBeanStyle{
public void testHello(String name) {
System.out.println("안녕하세요"+name+"님!");
}
}
스프링 IoC컨테이너를 이용해서 작업
public class MyBeanTest_Spring_BeanFactory {
public static void main(String[] args) {
//MyBeanStyleA obj = new MyBeanStyleA();//빈이 아님 그냥 자바객체
//1. xml을 파싱(xml로 만들어진 설정파일을 분석해서 <bean>으로 등록된 엘리먼트의 설정을 보고 객체를 생성
// => xml을 파싱해주는 기능은 스프링 내부에서 제공되는 객체를 이용
Resource res = new ClassPathResource("/config/bean.xml");//src부터 찾는다.
//ClassPathResource는 bean.xml 파일 분석
//bean.xml에서 A,B바꾸면 코드한줄안바꿔도 교체됨
System.out.println("+++++++++++++++Resource객체생성후++++++++++++++++++");
//2. 스프링이 제공하는 IoC컨테이너(객체를 생성하고 관리하는 기능을 갖고 있는 클래스 - ConnectionFactory같은 역할을 담당하는 클래스)
// 클래스를 생성
// => 객체를 요청하면 Resource객체 내부에서 파싱된 정보를 이용해서 객체를 생성해서 필요한 곳으로 넘겨준다.
BeanFactory factory = new XmlBeanFactory(res);
System.out.println("+++++++++++++++IoC 컨테이너 객체생성후++++++++++++++++++");
//3. 원하는 객체를 찾아오기(lookup)
MyBeanStyle obj = (MyBeanStyle)factory.getBean("mybean");
MyBeanStyle obj2 = (MyBeanStyle)factory.getBean("mybean");
if(obj==obj2) {
System.out.println("같은객체");
}else {
System.out.println("다른객체");
}
System.out.println("+++++++++++++++getBean호출될때++++++++++++++++++");
run(obj);
show(obj);
change(obj);
}
public static void run(MyBeanStyle obj) {
System.out.println("====================");
obj.testHello("BTS");
System.out.println("====================");
}
public static void show(MyBeanStyle obj) {
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
}
public static void change(MyBeanStyle obj) {
System.out.println("********************");
obj.testHello("BTS");
obj.testHello("BTS");
System.out.println("********************");
}
}

스프링 IoC컨테이너를 이용해서 작업
public class MyBeanTest_Spring_ApplicationContext {
public static void main(String[] args) {
//MyBeanStyleA obj = new MyBeanStyleA();//빈이 아님 그냥 자바객체
//1. IoC컨테이너를 생성- ApplicationContext
ApplicationContext factory = new ClassPathXmlApplicationContext("/config/bean.xml");
System.out.println("+++++++++++++++ApplicationContext 객체생성후++++++++++++++++++");
//MyBeanStyle타입의 obj가 스프링컨테이너가 관리하는 빈
MyBeanStyle obj = (MyBeanStyle)factory.getBean("mybean");
System.out.println("+++++++++++++++ getBean후++++++++++++++++++");
run(obj);
show(obj);
change(obj);
}
public static void run(MyBeanStyle obj) {
System.out.println("====================");
obj.testHello("BTS");
System.out.println("====================");
}
public static void show(MyBeanStyle obj) {
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
obj.testHello("BTS");
}
public static void change(MyBeanStyle obj) {
System.out.println("********************");
obj.testHello("BTS");
obj.testHello("BTS");
System.out.println("********************");
}
}

<?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="mybean" class="app3.MyBeanStyleA" scope="prototype"/> -->
<!-- scope를 prototype으로 정의하면 요청할때마다 객체를 생성해서 리턴 -->
<bean id="mybean" class="app3.MyBeanStyleA"/>
<bean id="account" class="exam01.Account"/>
<bean id="tv" class="exam02.SamsungTV"/>
</beans>
첨부된 파일을 Spring 컨테이너로부터 객체를 넘겨 받아 작업할 수 있도록 수정하세요
exam.xml을 생성해서 정의합니다.
public class Account {
private String accId;
private long balance=1000000;
public void setAccId(String accId){
this.accId = accId;
}
public Account() {
System.out.println("기본생성자 - Account");
}
public Account(String accId, long balance) {
super();
this.accId = accId;
this.balance = balance;
System.out.println("매개변수 2개 생성자 - Account");
}
public String getAccId(){
return this.accId;
}
//입금하기
public void input(long money){
balance = balance+money;
}
//출금하기
public void output(long money){
balance = balance-money;
}
//잔액조회하기
public long getBalance(){
return balance;
}
}
public class AccountDemo {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
ApplicationContext factory = new ClassPathXmlApplicationContext("/config/bean.xml");
Account acc = (Account)factory.getBean("account");
acc.setAccId("111-222-3333");
System.out.println("************은행업무 프로그램**************");
System.out.println("현재 잔액은:"+acc.getBalance()+"입니다.");
System.out.println("어떤 작업을 하시겠습니까?");
System.out.print("1.입금");
System.out.print("2.출금");
System.out.println("3.조회");
System.out.println("원하는 작업을 선택하세요.");
int num = key.nextInt();
switch(num){
case 1:
System.out.println("입금금액을 입력하세요");
acc.input(key.nextLong());
System.out.println(acc.getAccId()
+"계좌의 현재잔액은 "+acc.getBalance());
break;
case 2:
System.out.println("출금금액을 입력하세요");
acc.output(key.nextLong());
System.out.println(acc.getAccId()
+"계좌의 현재잔액은 "+acc.getBalance());
break;
case 3:
System.out.println(acc.getAccId()
+"계좌의 현재잔액은 "+acc.getBalance());
break;
default:
System.out.println("잘못선택하셨습니다.");
System.exit(0);
}
}
}
<?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="mybean" class="app3.MyBeanStyleA" scope="prototype"/> -->
<!-- scope를 prototype으로 정의하면 요청할때마다 객체를 생성해서 리턴 -->
<bean id="mybean" class="app3.MyBeanStyleA"/>
<bean id="account" class="exam01.Account"/>
<bean id="tv" class="exam02.SamsungTV"/>
</beans>

ApplicationContext를 이용해서 작업할 수 있도록 변경하세요
LgTV와 SamsungTV를 바꾸시며 테스트해보세요
exam.xml에 추가합니다.
bean.xml에서 exam01을 처리하신 분들은 xml을 생성해보세요
public interface TV {
void powerOn();
void powerOff();
void volumeUp();
void volumeDown();
}
public class SamsungTV implements TV{
public SamsungTV() {
System.out.println("기본생성자 - SamsungTV");
}
public void powerOn() {
System.out.println("SamsungTV---전원 켠다.");
}
public void powerOff() {
System.out.println("SamsungTV---전원 끈다.");
}
public void volumeUp() {
System.out.println("SamsungTV---소리 올린다.");
}
public void volumeDown() {
System.out.println("SamsungTV---소리 내린다.");
}
}
public class LgTV implements TV{
public void powerOn() {
System.out.println("LgTV---전원 켠다.");
}
public void powerOff() {
System.out.println("LgTV---전원 끈다.");
}
public void volumeUp() {
System.out.println("LgTV---소리 올린다.");
}
public void volumeDown() {
System.out.println("LgTV---소리 내린다.");
}
}
public class TVUser {
public static void main(String[] args) {
ApplicationContext factory
= new ClassPathXmlApplicationContext("/config/bean.xml");
TV tv = (TV)factory.getBean("tv");
tv.powerOn();
tv.volumeUp();
tv.volumeDown();
tv.powerOff();
}
}
<?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="mybean" class="app3.MyBeanStyleA" scope="prototype"/> -->
<!-- scope를 prototype으로 정의하면 요청할때마다 객체를 생성해서 리턴 -->
<bean id="mybean" class="app3.MyBeanStyleA"/>
<bean id="account" class="exam01.Account"/>
<bean id="tv" class="exam02.SamsungTV"/>
</beans>

DI연습하기
생성자방식으로 작업하세요
OOP특성이 적용되도록 수정하세요

public interface AbstractDice {
int getDiceValue();
}
public interface AbstractPlayer {
void play();
int getTotalValue();
}
public class Player implements AbstractPlayer{
AbstractDice d;//상위버전으로 만들어야 유연하게 사용할수있음=유지보수적게해도됨
int totalValue=0;//totalValue변수는 주사위를 굴리고 얻은 결과가 저장되므로 컨테이너가 생성해주지 않아도 된다.
public Player() {
}
public Player(AbstractDice d) {
super();
this.d = d;
System.out.println("매개변수 1개 생성자 - Player");
}
public void play(){
totalValue=0;
for (int i = 0; i < 3; i++) {
totalValue+=d.getDiceValue();
}
}
public int getTotalValue(){
return totalValue;
}
}
public class Dice extends Random implements AbstractDice{
public Dice() {
System.out.println("기본 생성자 - Dice");
}
public int getDiceValue(){
return nextInt(6)+1;
}
}
public class Test01 {
public static void main(String[] args) {
// Player p = new Player();
// p.play();
ApplicationContext factory
= new ClassPathXmlApplicationContext("/config/constructor.xml");
AbstractPlayer player = (AbstractPlayer)factory.getBean("player");
// AbstractPlayer player = factory.getBean("player",AbstractPlayer.class);
// 이렇게도 표현할 수 있다 보여준거. 이러면 캐스팅 안해도됨
player.play();
System.out.println("세번 굴린 주사위의 합:"+player.getTotalValue());
}
}
<?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="dao" class="basic.MemberDAO"/>
<bean id="insa" class="basic.InsaImpl">
<!-- constructor-arg가 정의된 갯수를 보면서 매개변수가 몇 개인지 파악
constructor-arg가 하나면 매개변수 한 개인 생성자를 호출하고
ref bean="dao"에 의해서 매개변수의 타입이 dao로 등록된 빈의 타입이라는 것을 판단한다.
-->
<constructor-arg><!-- 매개변수1개 -->
<!-- bean의 id가 dao인 빈을 연결 -->
<ref bean="dao"/>
</constructor-arg>
</bean>
<bean id="dice" class="di.constructor.exam01.Dice"/>
<bean id="player" class="di.constructor.exam01.Player">
<constructor-arg ref="dice" /><!-- 위의꺼 약식으로 표현한것 -->
</bean>
</beans>
본 포스팅은 멀티캠퍼스의 멀티잇 백엔드 개발(Java)의 교육을 수강하고 작성되었습니다.