카테고리 없음

0302 오전수업

logloglog 2021. 3. 2. 11:45

가져와서 쓰는것에대한 버전관리를 해야함

예전에는 jar를 가지고 다녓음

근데 변경이생기면?

해당 라이브러리에 대한 관리가 필요하다 

출처는 고정을 시키고, 버전은 실제로 우리가 가져오는게 아니고, 우리가 어떤 버전을 쓰겠다는 명세를 주면 명세에 의해 자르를 가지고 오자..  이부분을 Maven build로 해결하게됨

 

메이븐은 자유도가 높지않은 대신 표준화되어있따 (ANT 랑 비교했을때)

 

빌드업을 유지할떄 필요한게 maven이다

 


#1 빌드란?

 - 소스코드 파일을 컴퓨터에서 실행할 수 있는 독립 소프트웨어 가공물로 변환하는 과정 또는 그에 대한 결과물 이다.
 - 이를 좀더 쉽게 풀어 말하자면 우리가 작성한 소스코드(java), 프로젝트에서 쓰인 각각의 파일 및 자원 등(.xml, .jpg, .jar, .properties)을 JVM이나 톰캣같은 WAS가 인식할 수 있는 구조로 패키징 하는 과정 및 결과물이라고 할 수 있다.

 

#2 빌드 도구(Build tool)

 - 빌드 도구란 프로젝트 생성, 테스트 빌드, 배포 등의 작업을 위한 전용 프로그램.
 - 빠른기간동안 계속해서 늘어나는 라이브러리 추가, 프로젝트를 진행하며 라이브러리의 버전 동기화의 어려움을 해소하고자 등장.
 - 초기의 java 빌드도구로 Ant를 많이 사용하였으나 최근 많은 빌드도구들이 생겨나 Maven이 많이 쓰였고, 현재는 Gradle이 많이 쓰인다.
(Ant는 스크립트 작성도 많고, 라이브러리 의존관리가 되지 않아 불편함)

 

2. Maven

#1 정의 및 특징

 - Maven은 자바용 프로젝트 관리도구로 Apache Ant의 대안으로 만들어졌다.
 - Maven은 Ant와 마찬가지로 프로젝트의 전체적인 라이프 사이클을 관리하는 도구 이며, 많은 편리함과 이점이 있어 널리 사용되고 있다.
   (프로젝트의 작성부터 컴파일, 페트스 등 프로젝트 라이프사이클에 포함되는 각 테스트를 지원해준다.)

 - Maven은 필요한 라이브러리를 특정 문서(pom.xml)에 정의해 놓으면 내가 사용할 라이브러리 뿐만 아니라 해당 라이브러리가 작동하는데에 필요한 다른 라이브러리들까지 관리하여 네트워크를 통해서 자동으로 다운받아 준다.
 - Maven은 중앙 저장소를 통한 자동 의존성 관리를 중앙 저장소(아파치재단에서 운영 관리)는 라이브러리를 공유하는 파일 서버라고 볼 수 있고, 메이븐은 자기 회사만의 중앙 저장소를 구축할수도 있다.
 - 간단한 설정을 통한 배포 관리가 가능 하다.


출처: https://goddaehee.tistory.com/199 [갓대희의 작은공간]


문제점 : 톰캣이 잘 터진다

어떤경우?

1. 프로젝트에선 메이븐 빌드로 자르가 들어가잇는데 톰캣은 못읽어

2. 메이븐에서 자르를 가지고오는데 뭔가 추가될때마다 톰캣이 막 돌아 (이클립스가 중간연계를 안하니가) 그러다가 터짐

 

어떻게함?

 

메이븐에서 pom.xml이 명세임

여기에 있는 자르들을 인터넷상에서 가져오게됨

이떄 톰캣을 잠깐 꺼주는게 방법임

 

메이븐은 가져올떄 기록을 함. 가지고와서기록하는게 아니고... 근데 뭔가받아오다가 인터넷상에서 뭔가 이상이 발생하면 그 기록이 안남음. 가져오지않았는데 가져왓다고 생각함.  그래서 항상 의심해야함. 인터넷 상황에따라 달라질수잇으니까

 

pom.xml 구성 > jar(libary) 정보 명세 역할> maven build

 

<출처> repository 즉  xml 에선 <repositories> : maven 에서 쓰고잇는 디폴트밸류가잇다.

그래서 안주면, maven repository가 제공되고있다.

 

ex)

 <repositories>
      <repository>
         <id>oracle.ojdbc6</id>
         <url>http://www.datanucleus.org/downloads/maven2/</url>
      </repository>
   </repositories>

 

<버전> property 즉 xml 에선 <properties> :디폴트값이없음. 

ex)

  <properties>
      <java-version>1.8</java-version>
      <org.springframework-version>4.2.3.RELEASE</org.springframework-version>
      
      <oracle.ojdbc-version>11.2.0.3</oracle.ojdbc-version>
      <commons.dbcp2-version>2.5.0</commons.dbcp2-version>
      <org.mybatis-version>3.5.3</org.mybatis-version>
      <org.mybatis.spring-version>2.0.3</org.mybatis.spring-version>
      
      <org.aspectj-version>1.6.10</org.aspectj-version>
      <org.slf4j-version>1.6.6</org.slf4j-version>
   </properties>

 

 

<이름> id 즉 xml 에선 <dependencies> : 이름을 고유하게하려다보니까 길어짐.  그래서 세분화시켜서 <groupid> <artifactid>등..

 <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-webmvc</artifactId>
         <version>${org.springframework-version}</version>
      </dependency>

 

 

 

 

ojdbc 같은 애들은 레퍼지터리가 없음 .디폴트값쓰겠다는뜻

 

 

버전관리들을 위에서 한눈에확인할수있도록 프로퍼티스를 위에 올려놓은것 그래서 이 안에 태그네임 (spring-framework.version)만 봐도 어떤 자르에 어떤 버전 쓰고잇구나 한눈에 확인할수있도록 나열하는데에도 목적이있으므로 (명세서니까)

연두색은 아이디를 고유하게 하기위해 나눠놓은것( 고유하다는것은 길어진다는걸 의미하니까)

 

 

4버전은 rest방식을 위한 컨트롤러가 따로 마련되어있다.

3버전으로도 가능은 한데 4버전이 편함

 

우리가 왜 의존주입을 시켜야하나?


dependency injection

(의존성 주입)

부품이 되는게 의존성이고 조립하는게 주입이다.

 

주입에는 두가지 방법이 있는데

Setter injection (세터를 통해 주입하는 방법) 

  ex) a.setB(b);

Construction injection (생성자를 통해 주입하는 방법)

  ex) A a = new A(b);

 

스프링의 가장 기본적인 능력이 부품을 조립하는 능력임


 

클래스를 만들때 필요한 인스턴스를

의존적으로 만들어야한다는게(셋메서드로 받아서 할당해야함) 원칙임 > SetMethod()

 

그래서 커맨드부트스트랩 리뉴얼할때 클래스에 셋메서드가 없다? 다 갈아없어야함 new Instance XXXX 스프링 얹을수가없다.

 

new 안쓰고 set method로 인스턴스할당한다.

 


계산기 프로그래밍 (결합도 높게해보고 낮게도해보고)

package com.spring.operation;

public interface Operation {

	public int exe(int a , int b); //두개의 정수를 받았음
	
	
}

 

 

이걸 구현하는 4개의 클래스

package com.spring.operation;

public class Summation implements Operation {

	@Override
	public int exe(int a, int b) {
		
		return a+b;
	}

}

 

package com.spring.operation;

public class Minus implements Operation {

	@Override
	public int exe(int a, int b) {
		return a-b;
	}

}

 

등 4개의 모듈

 

옛방식으로 하면

4개의 모듈가지고있는 caculator 

 

package com.spring.operation;

public class Calculator {

	private Operation sum = new Summation();
	//타입은 오퍼레이션인데 이름은 서메이션
	//더하기할때 sum을 호출하면됨
	
	private Operation minus = new Minus();
	private Operation div = new Divide();
	private Operation multi = new Multi();
	
	public int sum(int a, int b) {
		return sum.exe(a, b);
	}//밖에서는 calculator의 sum 쓰겠지만 실질적으론 summation의 exe쓰는거임
	
	public int minus(int a, int b) {
		return minus(a, b);
	}
	
	public int div(int a, int b) {
		return div(a, b);
	}
	
	public int multi(int a, int b) {
		return multi(a, b);
	}
	
}

 

 

 

 

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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


</beans>

 

beans : 빈등록

프로퍼티의 네임이 아예 셋메서드의 이름으로 나온다.

 

sql  / dao /service /service의 프로퍼티에 sql와 dao 조립해줬었음

 

이렇게 인스턴스하나만든거임
각각의 인스턴스를 만들었을:뿐 조립되진않앗따 1~4를 5에 조립해야함

프로퍼티의 네임은 셋메서드!!!

밸류는 인스턴스타입을 주는거고 레퍼런스는 위에서만들어둔거 주는거임 (인스턴스이름인 빈의 아이디)

 

 

 

셋메서드가 자동완성으로 뜬다.

<?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="sum" class = "com.spring.operation.Summation"></bean> 
	<bean id="minus" class = "com.spring.operation.Minus"></bean>
	<bean id="div" class = "com.spring.operation.Divide"></bean>
	<bean id="multi" class="com.spring.operation.Multi"></bean>
	
	<bean id="calc" class="com.spring.operation.Calculator">
		<property name="sum" ref="sum"></property>
		<property name="minus" ref="minus"></property>
		<property name="div" ref="div"></property>
		<property name="multi" ref="multi"></property>
	</bean>
	
</beans>

	

 

널이 터지는 이유: sum 인스턴스가 없음

 

이부분에서 터진다 즉 인스턴스 주입이 안됐다

 

xml로 의존주입하는녀석 application context 종류중에 genericXml어쩌구임

 

package com.spring.main;

import java.util.Scanner;

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

import com.spring.operation.Calculator;
import com.spring.operation.Operation;
import com.spring.operation.Summation2;

public class Main {

	public static void main(String[] args) {
		//Calculator cal = new Calculator();
	
		//Operation sum = new Summation2(); //조립과정이 여ㄹ기에 있으면 sum2e도 못바꾸므로
		//커큘레이터에 모듈을 조립하는녀석도 따로잇어야함
		//main에서  summation을 2로 바꾸는방법 > 바꿀수없다.
		//애시당초 커큘레이터 만들떄부터 받아서쓸수있게끔 만들었어야함
		//cal.setSum(sum);
		//여기서 안할거니까 주석할거임

		ApplicationContext ctx = new GenericXmlApplicationContext("classpath:com/spring/context/application-context.xml");
		//5개 인스턴스만들고 4개를 커큘레이ㅅ터에 주입시킨상태를 맵에 저장시켜둔다
		
		//맵으로 만들어져있는데 맵의 겟을 맵핑해서 겟빈즈라고 해놧음
		//bean등록할떄 줬던 그 이름으로 꺼낸다
		Calculator cal =  ctx.getBean("calc",Calculator.class);//무슨타입인지모르니까 캐스팅
		// (Calculator) 로 캐스팅하는건 위험함 "calc"로 꺼내는걸 무조건 저 타입으로 캐스팅하려고하니까 안맞으면 터짐
		// 안맞으면 exception 이 아닌 null로 떨구는 방법.. "calc"이름으로 꺼내는 인스턴스가 Calculator.class 타입이 맞으면 캐스팅하고 안맞으면 null됨
		
		
		System.out.println("두개의 정수를 입력하세요");
		Scanner scan = new Scanner(System.in);
		int a = scan.nextInt(),  b = scan.nextInt();
		System.out.println("두 정수의 합은 " + cal.sum(a, b) + "입니다.");
		
		
	
	}

}

 

 

sum2 로 바꾸고싶음

이것만 바꾸면
바뀐다. .java 안바꾸고도

calc 이 덧셈이 잘되는지 테스트하고싶음


단위테스트는 왜 해야함?

모든 테스트는 변인통제가 우선임 (변수를 제거하고 그 성분만 테스트)

만약 application context 가 잘못돼서 노이즈가 발생했따면? 내잘못이 아님

이놈에 대한 노이즈를 배제하는게 기본임

배제하고 cal에 들어갈 sum 의 메서드에대한 테스트만 할거라는 뜻

즉 저 빨간놈을 누군가가 해줘야한다는 말임

그래서 스프링 테스트는 해당 context loader를 갖고있다. 개인이 만든게아니고

 

그래서 스프링 테스트란 모듈이 따로있는거임 이 점 때문에

 

application context에서 발생할수잇는 노이즈를 빼는거임

 

pom.xml의 버전 바꿔준다. 12버전 이상이어야함

 

 

test는 배포할거아니니까 text/java 에 만들자. 여기다가 만들면 톰캣에 배포가 안된다


오류

 

@어노테이션이 안된다

jar는 있는데 sts가 인식을 못하고잇음

c: 사용자폴더

싹다지웅고

다시 sts켜기

 

그리고 해당 프로젝트 우클릭 - 프러퍼티스 자바컴파일러

 

이제 임포트된다

 

메이븐이 인식이. jar는 있는데 이녀석이 인식을 못하고잇어서 조취를 취해준ㄱ더임


 test 할떄만 이 jar 쓰겠다는게 이 scope임
이 둘이 연계되어서 spring test가 되는거임 위에는 껍데기고 아래게 알맹이인거임

그래서 테스트 클래스위에 어노테이션 달게되는것

왼쪽놈이 우측가지고 우리가 로드안해도 컨텍스트 만듦
파란색과 같은 타입을 저 클래스패스에서 찾아서 calc 에 넣으라는 말을 함축한게 @Autowired 임

package com.spring.operation;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import junit.framework.Assert;

@RunWith(SpringJUnit4ClassRunner.class)
//application context 의 로딩이 필요하다
@ContextConfiguration("classpath:com/spring/context/application-context.xml")
public class TestCalculator {
	
	@Autowired //애는 스트링거임.알아서 땡겨와
	private Calculator calc;
	
	@Before
	public void init() {}//테스트메서드 규정/; 메서드명은 자유인데 파라미터는 받으면 안됨. 즉 뭘 받아와서 테스트하면안된다

	@Test
	public void test_sum() {
		//확실한 정수 주기 (변인통제)
		final int a = 3, b = 9;//변경 불가능한 (final) 확실한 정수
		Assert.assertEquals(112, calc.sum(a, b));
		//assert : 제이유닛의 클래스. 확인해주는
	}
}

run as junit