DI는 말 그대로 의존성을 주입한다 라는 뜻이다. 쉽게 설명하면 JAVA에서 객체를 new를 이용하여 생성하는데 이렇게 사용하지 않고 외부에서 생성한 객체를 세터 또는 생성자를 통해 사용하겠다는 의미이다. 이를 의존성 주입이라 한다. 의존성 주입 방법에는 세터를 이용하거나 생성자를 이용한 방법 두가지가 있다. 예제로는 생성자를 이용한 방법으로 예제를 공부하겠다
DI 사용하지 않은 예시
그림처럼 DI를 이용하지 않고 new를 사용하여 객체를 생성하게 되면 PetOwner와 Dog간 강한 결합이 생기게 되어 도그를 수정하면 PetOwner가 수정될 수 있다.
DI
반면 다음과 같이 Bean Container를 이용하여 객체를 생성하고 의존성 주입을 시켜주면 결합이 강하지 않다는 장점이 생긴다. 이때 Bean Container는 XML로 이루어져 있다.
DI 설명
다음 그림처럼 메인함수에서는 ApplicationContext라는 BeanContainer를 생성하고 미리 작성된 xml에 따라 ApplicationContext는 Dog, Cat, PetOwner라는 객체를 생성하고 Dog, Cat을 PetOwner에 의존성 주입한다. 스프링은 new방식 대신 DI방식을 권장한다.
2. 의존성 주입 실습
#1 프로젝트 생성
File > New > Spring Legacy Project를 클릭하고 다음과 같은 Simple Spring Maven 프로젝트를 생성한다. 프로젝트명은 원하는 프로젝트명을 사용해도 무방하다. 이 실습에서는 helloDI라는 프로젝트명을 사용하겠다.
프로젝트 생성
#2 AnimalType, Cat, Dog 생성하기
src/main/java에 클래스와 인터페이스를 담을 패키지를 생성한다 패키지명은 자유로워도 좋다. 패키지를 생성하였다면 패키지 아래에 AnimalType.java라는 인터페이스를 생성한다
인터페이스 코드는 다음과 같다 인터페이스를 implements할 cat, dog클래스들이 사용할 sound라는 메소드를 정의하고 있다.
AnimalType.java
package kr.ac.hansung.helloDI;
public interface AnimalType {
public void sound();
}
다음으로 Cat.java라는 클래스를 생성한다. 게터와 세터가 만들어져 있으며 AnimalType의 sound메소드를 사용하고 있다.
Cat.java
package kr.ac.hansung.helloDI;
public class Cat implements AnimalType {
public String getMyName() {
return myName;
}
public void setMyName(String myName) {
this.myName = myName;
}
private String myName;
@Override
public void sound() {
System.out.println("Cat name = " + myName + ":" + "Meow");
}
}
마지막으로 Dog.java라는 클래스를 생성한다. 게터와 세터가 만들어져 있으며 AnimalType의 sound메소드를 사용하고 있다.
Dog.java
package kr.ac.hansung.helloDI;
public class Dog implements AnimalType {
public String getMyName() {
return myName;
}
public void setMyName(String myName) {
this.myName = myName;
}
private String myName;
@Override
public void sound() {
System.out.println("Dog name = " + myName + ":" + "Bow Wow");
}
}
#3 PetOwner클래스 생성하기
petOwner클래스는 AnimalType의 animal을 받는다 이는 cat이나 dog를 받아서 사용하겠다는 의미이고 play라는 메소드와 생성자를 정의했다.
PetOWner.java
package kr.ac.hansung.helloDI;
public class PetOwner {
private AnimalType animal;
public PetOwner(AnimalType animal) {
this.animal = animal;
}
public void play() {
animal.sound();
}
}
#4 animal.xml 생성하기
Bean Container가 생성하기 위해 참고할 xml파일을 생성한다 코드는 다음가 같다.
<bean id = "dog"> 부분이 dog라는 클래스의 객체를, <bean id = "cat"> 부분이 cat이라는 클래스의 객체를 <bean id = petOwner"> 부분이 petOwner의 객체를 생성하고 <constructor-arg ref = "dog">는 dog객체를 의존성 주입하겠다 라는 의미이며, <property name="myName" value="poddle">는 도그의 myName의 값을 poodle로 주겠다는 의미이다.
마지막으로 메인 함수인 MainApp.java를 다음과 같이 작성한다. ApplicationContext가 animal.xml을 바라보게 하고
petOwner의 person이 context의 getBean함수를 통해 객체를 가져와 사용하는 모습이다.
package kr.ac.hansung.helloDI;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("/kr/ac/hansung/helloDI/conf/animal.xml");
PetOwner person = (PetOwner) context.getBean("petOwner");
person.play();
context.close();
}
}
#5 프로젝트 Run
프로젝트를 Run 하게 되면 다음과 같은 결과를 확인할 수 있다.
결과화면
사용자는 animal.xml에서 정의한 대로 dog, cat, petOwner의 객체를 먼저 생성하고, 이후 dog를 petOwner에 주입하였으니 결과 화면에는 dog가 보이게 된다 만약 cat을 주입하고 싶다면 constructor-arg의 ref = cat으로 수정해주면 된다
버튼은 아래 그림과 같이 평상시에는 전류가 흐르지 않다가 사용자가 버튼을 눌렀을 시 전류가 흐르게 만든다.
버튼 구성
이러한 버튼을 사용하여 다음과 같은 회로를 구성한다
버튼, LED 회로도
회로 구성을 완료하였다면 다음과 같은 코드를 작성한다. 버튼에 연결된 핀 12, 13번에 전류가 흐른다면 LED를 ON 하는 코드이다. 이때 12, 13핀에 전류가 흐르는지 확인하기 위해 digitalRead함수를 사용했다. digitalWrite가 디지털 방식으로 전류를 ON/OFF 했다면 digitalRead는 전류가 들어오는지 여부를 확인할 때 사용한다
int led1 = 7;
int led2 = 6;
int key1 = 13;
int key2 = 12;
void setup()
{
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(key1, INPUT);
pinMode(key2, INPUT);
}
void loop()
{
if( digitalRead(key1) == HIGH )
digitalWrite(led1, HIGH);
else
digitalWrite(led1, LOW);
if( digitalRead(key2) == HIGH )
digitalWrite(led2, HIGH);
else
digitalWrite(led2, LOW);
delay(100);
}
코드를 작성하고 현재 view 폴더와 loginform.jsp, help.jsp, error.jsp를 만들지 않았으므로 생성해주도록 한다.
먼저 WebContent 아래에 view라는 폴더를 생성시킨다. 이후 아래 그림처럼 loginform.jsp, help.jsp, error.jsp를 생성하고 다음과 같은 코드를 작성한다
view 폴더 구성
loginform.jsp
//loginform.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Insert title here</title>
</head>
<body>
This is Login Page.
<form action="/MVCexample/doLogin" method="get">
customer ID(id1, id2, id3, id4, id5)<br/>
<input type="text" name="customerId"/> <br/>
<input type="submit" value="submit"/> <br/>
</form>
</body>
</html>
help.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Insert title here</title>
</head>
<body>
This is help Page.
</body>
</html>
error.jsp
<%@ page language="java" contentType="text/html; charset=US-ASCII" pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Insert title here</title>
</head>
<body>
This is error Page.
</body>
</html>
모두 작성을 완료하였다면 index.jsp에서 링크를 클릭 시 다음과 같이 forward 된 것을 확인할 수 있다.
loginform.jsp
#5 Model 작성
loginform에서 사용자가 입력하는 id의 실질적인 객체를 만들기 위해 Model을 생성한다 먼저 MVCexample >> Java Resources >> src >> model 패키지를 생성한다. 이후 아래 사진과 같이 Customer 클래스를 생성한다
model 생성
생성한 Class의 코드는 다음과 같다 id, name, email을 가지고 있으며 Customer이라는 생성자와, 각각의 게터, 세터 메소드가 정의되어있다.
package model;
public class Customer {
private String id;
private String name;
private String email;
public Customer(String id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
#6 Service 생성
실제로 만든 모델에 데이터를 저장하거나, 데이터를 읽어오거나 하는 함수들이 정의된 서비스이다. 사용자의 요청이 들어왔을 때 서블릿에서 이를 처리하는 함수를 구현해도 상관없으나 Service로 분리하여 보다 보기 좋은 코드를 구현한다
model 생성과 같은 방법으로 MVCexample >> Java Resources >> src >> service 패키지를 생성한다. 이후 다음 그림처럼 CustomerService 클래스를 생성한다
service 생성
실제 코드는 다음과 같다. 먼저 CustomerService를 생성하면 customers라는 Map을 생성한다 이때 String은 id, 값으로는 Customer 모델을 받고 customers 객체가 생성될 때 id1~id5의 정보를 미리 저장해 놓는다. 또한 DoLogin 서블릿에서 사용할 findCustomer함수를 정의한다 이는 검색한 아이디가 있을 경우 id의 cusomer을 반환하고 없을 경우 null을 반환한다.
package service;
import java.util.HashMap;
import java.util.Map;
import model.Customer;
public class CustomerService {
private Map<String, Customer> customers;
public CustomerService() {
customers = new HashMap<String, Customer>();
addCustomer( new Customer("id1", "test1", "test1@naver.com"));
addCustomer( new Customer("id2", "test2", "test2@naver.com"));
addCustomer( new Customer("id3", "test3", "test3@naver.com"));
addCustomer( new Customer("id4", "test4", "test4@naver.com"));
addCustomer( new Customer("id5", "test5", "test5@naver.com"));
}
public void addCustomer(Customer customer) {
customers.put(customer.getId(), customer);
}
public Customer findCustomer(String id) {
if(id != null) {
return (customers.get(id.toLowerCase()));
}
else{
return null;
}
}
}
#6 DoLogin 서블릿 작성
loginform.jsp에서 사용자가 정해진 id를 입력하면 이를 실질적으로 처리할 서블릿인 DoLogin 서블릿을 생성한다.
다음 그림과 같이 URL Mapping을 /doLogin으로 생성한다.
DoLogin 서블릿 생성
DoLogin의 코드는 다음과 같다. loginform.jsp에서 사용자가 입력한 customerId의 값을 저장하고
CustomerService의 객체를 선언한다. 다음으로 findCustomer함수를 사용하여 사용자가 입력한 결과를 Customer라는 Model객체에 저장하여 이를 setAttribute라는 함수를 통해 customer라는 이름으로 저장하여 success.jsp로 forward 한다.
dfs를 사용하여 방문여부를 체크하고, 더불어 array의 값이 3일때를 체크하는 방식을 사용하였다.
방문여부를 체크할 bool array가 dfs재귀함수 호출전에 체크해줘야한다는 주의사항이 있다.
2. 코드
#include <string.h>
#include <iostream>
using namespace std;
int num = 0;
int ary[16][16];
int bo[16][16] = { 0 };
int result = 0;
int dx[4] = { -1, 1 ,0, 0 };
int dy[4] = { 0, 0, -1, 1 };
void dfs(int x, int y) {
bo[1][1] = 1;
if (ary[x][y] == 3) {
result = 1;
}
else {
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx < 1 || ny < 1 || nx >= 14 || ny >= 14 || ary[nx][ny] == 1 || bo[nx][ny]){
continue;
}
else{
bo[nx][ny] = 1;
dfs(nx, ny);
}
}
}
}
int main()
{
for (int i = 0; i < 10; i++) {
scanf("%d", &num);
memset(bo, 0, sizeof(bo));
for (int m = 0; m < 16; m++) {
for (int n = 0; n < 16; n++) {
scanf("%1d", &ary[m][n]);
}
}
result = 0;
dfs(1, 1);
cout << "#" << num << " " << result << endl;
}
}
Java Server Pages로서 정적 HTML과 동적인 컨텐츠를 섞어놓은 기술 서블릿 처럼 동적인 페이지를 기술 할 수 있다.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Order Confirmation</TITLE>
<LINK REL=STYLESHEET
HREF="JSP-Style.css"
TYPE="text/css">
</HEAD>
<BODY>
Thanks for ordering <%= request.getParameter("title") %>!
</BODY>
</HTML>
다음은 JSP예시이다. <%= request.getParameter("title")%> 부분이 HTML 내부에 동적인 JAVA코드가 삽이되어있는 부분이다. JSP 가 실행되면 서블릿(Servlet)으로 변환되며웹 어플리케이션 서버에서 동작되면서 필요한 기능을 수행하고
그렇게 생성된 데이터를 웹페이지와 함께 클라이언트로 응답한다.
2. JSP 와 Servlet의 차이
JSP는 HTML 내부에 JAVA코드를 넣어 처리하고 Servlet은 JAVA코드내에 HTML을넣어 표시한다. 따라서 Servlet은 JSP보다 코드를 읽고 사용하기에 불편하다는 단점이 존재한다 따라서 Servlet은 데이터를 프로세싱 하기에 적합하고, JSP는 데이터를 보여주기에 적합하다
3. JSP 문법
1) JSP Expression
<%= 내용 %> 으로서 out 객체를 통해 print해주는 역할을 한다.
2) JSP Scriptlets
<% Java Code %> 로서 좀 더 복잡한 기능 구현을 하고 싶다면 <% %>사이에 JAVA코드를 넣어서 사용가능하다
ex) <% if(a == 1) out.println("aa"); %>
3) JSP Declarations
<%! private int count = 0; %> 처럼 필드, 메소드를 정의하는 방법이다. 사용자는 정의한 count 를
<%= count %>를 통해 출력하거나 사용할 수 있다.
4)JSP Directive
JSP전체 구조에 영향을 미친다
JSP 서블릿 컨테이너에 지시를 하는 역할을한다
#1 page Directive
페이지 지시는 JSP페이지의 가장 위에 적어주며 import하거나 페이지에 명령을 내리는곳에 사용한다
<%@ page import = "java.util.*" %>
<%@ page contentType = "text/html" %>
#2 include Directive
<%@ include file = "test_url"> 모든 페이지 하단부에 있는 주소같은 부분을 복사 붙여넣기 하여 사용하는것은 좋지않은 방법이다 따라서 이러한 include를 통하여 사용하는것이 좋다.
#3 taglib Directive
태그를 모아놓은 라이브러리로서 외부의 라이브러리 파일을 JSP내에 HTML이나 XML태그처럼 사용할 수 있게 함
등등 여러 말로 표현할 수 있겠지만 예를 들어 3초 간격으로 작동하는 모터가 있다고 가정하자, 모터가 3초마다 움직이게 프로그래밍을 해야 할 텐데 이때 작은 모터에 큰 컴퓨터를 사용하는 건 매우 비효율적이다 따라서, 소형 컴퓨터를 사용하면 매우 효율적일 테고, 아두이노, 라즈베리파이를 초소형 컴퓨터로 생각하면 좋을 것 같다.
참고자료 : 아두이노 스펙 & 아두이노 기본 핀 설명 아두이노 스펙기본 핀 설명
2. 통합 개발 환경 (IDE) 설치하기
아두이노 공식 홈페이지에서 제공하는 소프트웨어를 다운로드한다. 홈페이지에서는 Online IDE와 Offline IDE를 제공하고 있으며 실습은 Offline IDE를 다운로드하여 진행하도록 할 예정이다.