유정잉

51일차 스프링 [ 주입 DI ] 본문

네이버 클라우드 부트캠프/복습 정리

51일차 스프링 [ 주입 DI ]

유정♡ 2024. 5. 2. 11:54

[ DI 종류 4개 : 자동, 생성자, 컬렉션, Set ]

 

[ ☆★ 주입  ]

외부에서 객체 IoC를 만들면 -> 주입 -> 내부로 

    즉, beans.xml(외부)에서 객체를 만들어서 -> 주입 -> MainClass.java(내부)로 주입 

   생성자를 만들어서 주입할 수도 있고 메서드를 만들어서 자동 주입할 수도 있고 .. 여러 종류가 있는데

   가장 많이 쓰이는 방식이 자동 주입 !!!

 


[ Auto_DI - project ] - 가장 중요 가장 많이 쓰이는 방법 

 

1) Test.java 파일에 Data 객체러 필드 선언 후 Getter&Setter 생성

package beans;

public class Test {

	private Data d1;
	private Data d2;
	
	public Data getD1() {
		return d1;
	}
	public void setD1(Data d1) {
		this.d1 = d1;
	}
	public Data getD2() {
		return d2;
	}
	public void setD2(Data d2) {
		this.d2 = d2;
	}
	
	
}

 

2) Test2.java 파일에 

package beans;

public class Test2 {
	
    private Data2 d1;
    private Data2 d2;

    public Data2 getD1() {
        return d1;
    }

    public void setD1(Data2 d1) {
        this.d1 = d1;
    }

    public Data2 getD2() {
        return d2;
    }

    public void setD2(Data2 d2) {
        this.d2 = d2;
    }
}

 

3) Test3.java 파일에 

package beans;

public class Test3 {

	private int d1;
	private String d2;
	private Data2 d3;
	private Data2 d4;
	
	public Test3(Data2 d3, Data2 d4) {
		this.d3=d3;
		this.d4=d4;
	}
	
	public Test3(int d1, String d2, Data2 d3, Data2 d4) {
		this.d1=d1;
		this.d2=d2;
		this.d3=d3;
		this.d4=d4;
	}

	public int getD1() {
		return d1;
	}

	public void setD1(int d1) {
		this.d1 = d1;
	}

	public String getD2() {
		return d2;
	}

	public void setD2(String d2) {
		this.d2 = d2;
	}

	public Data2 getD3() {
		return d3;
	}

	public void setD3(Data2 d3) {
		this.d3 = d3;
	}

	public Data2 getD4() {
		return d4;
	}

	public void setD4(Data2 d4) {
		this.d4 = d4;
	}
	
}

 

4) beans.xml에 객체 등록

     1 - set 메서드로 주입하는 방법 : <property>안에 1)class="" 2)ref="data"

     2 - autowire="byName"으로 자동 주입하는 방법 : 프로퍼티 이름과 정의된 빈의 이름이 같은 것을 찾아 자동으로 주입

     3 - autowire="byType"으로 자동 주입하는 방법 : 프로퍼티 타입과 정의된 빈의 타입이 일치할 경우 자동으로 주입

<?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">
	                   
	                   
	<!-- set 메서드로 주입하는 방법 -->
	<bean id="test1" class="beans.Test">
		<property name="d1" ref="data"></property> <!-- Test.java class에 data객체 d1필드에 주사바늘 꼽듯이 주입 -->
		<property name="d2" ref="data"></property>
	</bean>
	<bean id="data" class="beans.Data" scope="prototype"></bean> <!-- 원래는 싱글톤인데 scope="prototype"으로 인해 싱글톤 아님 ! -->
	
	
	<!-- autowire="byType" : 프로퍼티 이름과 정의된 빈의 이름이 같은 것을 찾아 자동으로 주입한다 -->
	<bean id="test2" class="beans.Test" autowire="byName"></bean> <!-- autowire="byName" 이름이 같은 property 찾아서 자동으로 주입 -->
	
	<bean id="d1" class="beans.Data"></bean> <!-- bean으로 Data 객체 생성 d1과 d2 두개이기 때문에 두개 만들기 (필드명은 무조건 똑같이 설정)-->
	<bean id="d2" class="beans.Data"></bean> <!-- autowire="byName"로 할경우 필드명 무조건 똑같아야 함 다르면 등록 안 됨 !!! -->
	
	
	<!-- autowire="byType" : 프로퍼티 타입과 정의된 빈의 타입이 일치할 경우 자동으로 주입한다 -->
	<bean id="test3" class="beans.Test2" autowire="byType"></bean>
	<bean id="data2" class="beans.Data2" ></bean>
	
	
	<!-- 생성자를 통한 주입 -->
	<bean id="test4" class="beans.Test3">
		<constructor-arg ref="data2" index="0"></constructor-arg>
		<constructor-arg ref="data2" index="1"></constructor-arg>
	</bean>
	
	
	<bean id="test5" class="beans.Test3">
		<constructor-arg value="1" type="int"></constructor-arg>
		<constructor-arg value="문자"></constructor-arg>
		<constructor-arg ref="data2"></constructor-arg>
		<constructor-arg ref="data2"></constructor-arg>
	</bean>
	
</beans>

 

 

5) MainClass.java에서 출력 

package main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import beans.Test;
import beans.Test2;

public class MainClass {

	public static void main(String[] args) {
	
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("config/beans.xml");
	
		//set 메서드로 출력 
		Test t = ctx.getBean("test1", Test.class);
		System.out.println(t);
		System.out.println(t.getD1()); //set메서드로 객체의 주소값을 주입하고 get메서드로 객체의 주소값 출력 
		System.out.println(t.getD2());
		
		//autowire="byName" 자동주입으로 출력 
		Test t2 = ctx.getBean("test2", Test.class);
		System.out.println(t2.getD1());
		System.out.println(t2.getD2());
		
		//autowire="byType" 자동주입으로 출력 
		Test2 t3 = ctx.getBean("test3", Test2.class);
		System.out.println(t3.getD1());
		System.out.println(t3.getD2());
		
	}
}

위에 코드 출력 결과

 


[ Colleciont_DI - project ]

 

1) Test.java 파일에 List, Set, Map 필드 선언 후 Getter&Setter 선언

package beans;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class Test {

	private List<String> list1;
	private List<Integer> list2;
	private List<Data> list3;
	
	private Set<String> set1;
	private Set<Integer> set2;
	private Set<Data> set3;
	
	private Map<String, Object> map1;

	public List<String> getList1() {
		return list1;
	}

	public void setList1(List<String> list1) {
		this.list1 = list1;
	}

	public List<Integer> getList2() {
		return list2;
	}

	public void setList2(List<Integer> list2) {
		this.list2 = list2;
	}

	public List<Data> getList3() {
		return list3;
	}

	public void setList3(List<Data> list3) {
		this.list3 = list3;
	}

	public Set<String> getSet1() {
		return set1;
	}

	public void setSet1(Set<String> set1) {
		this.set1 = set1;
	}

	public Set<Integer> getSet2() {
		return set2;
	}

	public void setSet2(Set<Integer> set2) {
		this.set2 = set2;
	}

	public Set<Data> getSet3() {
		return set3;
	}

	public void setSet3(Set<Data> set3) {
		this.set3 = set3;
	}

	public Map<String, Object> getMap1() {
		return map1;
	}

	public void setMap1(Map<String, Object> map1) {
		this.map1 = map1;
	}
	
}

 

2) beans.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">
	                   
	                   
	<!-- List interface 컬렉션 -->
	<bean id="test1" class="beans.Test">
		<property name="list1"> <!-- name은 필드명과 똑같이 넣어줌 -->
			<list>
				<value>스프링1</value> <!-- default가 String이여서 아무것도 적지 않으면 String으로 인식 -->
				<value>스프링2</value>
				<value>스프링3</value>
			</list>
		</property>
		
		<property name="list2">
			<list>
				<value type="int">10</value>
				<value type="int">20</value>
				<value type="int">30</value>
			</list>
		</property>
		
		<property name="list3">
			<list>
				<bean class="beans.Data"></bean> <!-- Data 객체를 불러오는 법 -->
				<ref bean="data"></ref>
			</list>
		</property>
	
	
		<!-- set interface  -->
		<property name="set1">
			<set>
				<value>부트1</value>
				<value>부트2</value>
				<value>부트3</value>
			</set>
		</property>
		
		<property name="set2">
			<set>
				<value type='int'>1</value>
				<value type='int'>2</value>
				<value type='int'>2</value>
			</set>
		</property>
		
		<property name="set3">
			<set>
				<bean class="beans.Data"/>
				<ref bean="data"/>
				<ref bean="data"/>
			</set>
		</property>
		
		<property name="map1">
			<map>
				<entry key="k1" value="스프링"/>
				<entry key="k2" value='10' value-type="int"/>
				<entry key="k3">
					<bean class="beans.Data"/>
				</entry>
			</map>
		</property>
	
	
	</bean>
	
	<bean id="data" class="beans.Data"></bean>
	
	
	</beans>

 

3) MainClass.java에서 출력 List<>, Map<>, 를 이용한 컬렉션 주입 !!!

package main;
import java.util.List;
import java.util.Map;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import beans.Data;
import beans.Test;

public class MainClass {
	public static void main(String[] args) {
		
		ClassPathXmlApplicationContext ctx=
				new ClassPathXmlApplicationContext("config/beans.xml");
		
		
		Test t1=ctx.getBean("test1",Test.class);
		List<String> li=t1.getList1();
		for(String str:li) {
			System.out.println(str);
		}
		
		System.out.println("-----------------------------");
		
		List<Integer> li2=t1.getList2();
		for(int i:li2) {
			System.out.println(i);
		}
		
		System.out.println("-----------------------------");
		
		List<Data> li3=t1.getList3();
		for(Data d:li3) {
			System.out.println(d);
		}
		
		System.out.println("-----------------------------");
		
		Map<String, Object> m1=t1.getMap1();
		String s1=(String)m1.get("k1");
		int s2=(Integer)m1.get("k2");
		Data s3=(Data)m1.get("k3");
		
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
	}
}

위에 코드 출력 결과

 

 


 

[ Constructor_DI - project - 주입(생성자를 이용한 방법) ]

 

1) Test.java에 필드&함수 생성

package beans;

public class Test {

	private int d1;
	private double d2;
	private String d3;
	
	public Test() {
		System.out.println("Test 생성자");
		this.d1=0;
		this.d2=0.0;
		this.d3=null;
	}
	
	public Test(int d1) {
		System.out.println("Test 매개변수 int 생성자");
		this.d1=d1;
		this.d2=0.0;
		this.d3=null;
	}
	
	public Test(double d1) {
		System.out.println("Test 매개변수 double 생성자");
		this.d1=0;
		this.d2=d2;
		this.d3=null;
	}
	
	public Test(String d1) {
		System.out.println("Test 매개변수 String 생성자");
		this.d1=0;
		this.d2=0.0;
		this.d3=d3;
	}
	
	public Test(int d1, double d2, String d3) {
		this.d1=d1;
		this.d2=d2;
		this.d3=d3;
	}
	
	public void show() {
		System.out.println(d1);
		System.out.println(d2);
		System.out.println(d3);
	}
}

 

2) Test2.java에 데이터 만든거에 대한 객체 생성 

package beans;

public class Test2 {

	private Data d1;
	private Data d2;
	
	public Test2(Data d1, Data d2) {
		this.d1=d1;
		this.d2=d2;
	}
	
	public void show() {
		System.out.println(d1);
		System.out.println(d2);
	}
}

 

3) beans.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">
	                   
	                   
	<bean id="test" class="beans.Test" lazy-init="true"></bean>
	
	<bean id="test2" class="beans.Test" lazy-init="true">
		<constructor-arg value='10' type="int" /> <!-- 매개변수 int인 (int d1)생성자로 가서 this.d1에 value값 들어감  -->
	</bean>
	
	<bean id="test3" class="beans.Test" lazy-init="true">
		<constructor-arg value='10.10' type="double" /> <!-- 매개변수 double인 (double d2)생성자로 가서 this.d2에 value값 들어감  -->
	</bean>
	
	<bean id="test4" class="beans.Test" lazy-init="true">
		<constructor-arg value='문자열' /> <!-- type default가 String이라서 type="String" 안 적어줘도 됨 ! 매개변수 Stirng인 (String d3)생성자로 가서 this.d3에 value값 들어감  -->
	</bean>
	
	<bean id="test5" class="beans.Test" lazy-init="true">
		<constructor-arg value='10' type="int" index='0'/>
		<constructor-arg value='10.10' type="double" index='1'/>
		<constructor-arg value='문자열' type='java.lang.String'/> <!-- (int d1, double d2, String d3)에 한번에 value 값 들어감 -->
	</bean>
	
	<!-- 여기서 부턴 Test2 -->
	<bean id="test6" class="beans.Test2"> <!-- 여기서는 scope="prototype"으로 안 줘도 당연히 객체 주소 다름 -->
		<constructor-arg>
			<bean class="beans.Data" />
		</constructor-arg>
		<constructor-arg>
			<bean class="beans.Data" />
		</constructor-arg>
	</bean>
	
	<bean id="data" class="beans.Data" scope="prototype" />
	<bean id="test7" class="beans.Test2">
		<constructor-arg ref='data' /> <!-- 위에 id="data" 주소값을 참고할 수 있게끔 ref='data'로 준 것  -->
		<constructor-arg ref='data' /> <!-- 주소를 주입하면 beans.Test2에서 찾는 다는 뜻 / scope="prototype"으로 줘서 싱글톤 아님 객체 주소 다르게 출력 됨 -->
	</bean>
	
	
</beans>

 

4) MainClass.java 출력

package main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import beans.Test;
import beans.Test2;

public class MainClass {

	public static void main(String[] args) {
	
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("config/beans.xml");
		
		Test t1 = ctx.getBean("test",Test.class);
		t1.show();
		
		Test t2 = ctx.getBean("test2",Test.class);
		t2.show();
		
		Test t3 = ctx.getBean("test3",Test.class);
		t3.show();
		
		Test t4 = ctx.getBean("test4",Test.class);
		t4.show();
		
		Test t5 = ctx.getBean("test5",Test.class);
		t5.show();
		
		Test2 t6 = ctx.getBean("test6",Test2.class);
		t6.show();
		
		Test2 t7 = ctx.getBean("test7",Test2.class);
		t7.show();
	}
}

위에꺼 출력 결과

 

 


[ Set_DI - project ]

    Set 메서드에 값을 넣으려면 객체를 등록할 때 <property>를 사용한다 !

    이때 name 값은 필드명과 똑같이 줘야 한다 !

    Data 객체는 2가지 방법으로 값을 넣을 수 있다. 1) class를 통한 방법 2) ref를 통한 방법

    (set 주입이 많이 사용되는 방식은 아님 ! )

 

1) Test.java 파일에 필드 선언 후 Getter&Setter 생성

package beans;

public class Test {

	private int d1;
	private double d2;
	private String d3;
	private boolean d4;
	private Data d5;
	private Data d6;
	
	public int getD1() {
		return d1;
	}
	public void setD1(int d1) {
		this.d1 = d1;
	}
	public double getD2() {
		return d2;
	}
	public void setD2(double d2) {
		this.d2 = d2;
	}
	public String getD3() {
		return d3;
	}
	public void setD3(String d3) {
		this.d3 = d3;
	}
	public boolean isD4() {
		return d4;
	}
	public void setD4(boolean d4) {
		this.d4 = d4;
	}
	public Data getD5() {
		return d5;
	}
	public void setD5(Data d5) {
		this.d5 = d5;
	}
	public Data getD6() {
		return d6;
	}
	public void setD6(Data d6) {
		this.d6 = d6;
	}
}

2) beans.xml에 set 메서드를 활용한 객체 등록과 값 집어 넣는 방법 

<?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="test1" class="beans.Test"> <!-- 객체 등록 -->
		<property name="d1" value="200"></property> <!-- name은 필드명과 똑같이 --> <!-- set 메서드에 넣을라면 property 이용 -->
		<property name="d2" value="11.11"></property>
		<property name="d3" value="hi"></property>
		<property name="d4" value="true"></property>
		<property name="d5">
			<bean class="beans.Data"></bean> <!-- Data 객체는 class를 등록해야함 -->
		</property>
		<property name="d6" ref="data"></property> <!-- Data 객체는 ref를 통해서도 등록 가능 -->
	</bean>
		<bean id="data" class="beans.Data"></bean>
</beans>

 

3) MainClass.java 에서 출력 

package main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import beans.Test;

public class MainClass {

	public static void main(String[] args) {
	
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("config/beans.xml");
		
		Test t = ctx.getBean("test1", Test.class);
		System.out.println(t.getD1());
		System.out.println(t.getD2());
		System.out.println(t.getD3());
		System.out.println(t.isD4());
		System.out.println(t.getD5());
		System.out.println(t.getD6());
		
		ctx.close();
	}
}

 

위에 코드 출력 결과

 

 


[ JavaSetting - Project ]

1) Test1, Test2, Test3, Test4 기본생성자만 생성  

package beans;

public class Test {

	public Test() {
		System.out.println("test");
	}
}
package beans;

public class Test2 {
	
	public Test2() {
		System.out.println("test2");
	}

}
package beans;

public class Test3 {

	public Test3() {
		System.out.println("test3");
	}
}
package beans;

public class Test4 {

	public Test4() {
		System.out.println("test4");
	}

}

 

2) config package에 BeanClass.java class 생성(beans.xml대신)

package config;

import org.springframework.context.annotation.Configuration;

 

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션

@Configuration

public class BeanClass {

}

 

여기에서는 bean.xml에서 <bean id="test1" class="beasn,Test" />으로 객체를 등록하는 방식과 달리. 

@Bean을 통해서 객체를 등록 한다. 이때 메서드 이름이 bean의 이름(주소값)이 된다.

package config;

 

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

 

import beans.Test;

 

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션

@Configuration

public class BeanClass {

 

      //빈 객체 등록하겠단 의미 (xml에선 <bean>으로 객체 등록했었음)

      //<bean id="test1" class="beans.Test"></bean> 랑 같은 의미

     @Bean

         public Test test1() { //메서드 이름이 bean의 이름(주소값)이 된다.

              Test t1=new Test();

               return t1;

         }

}

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

import beans.Test;
import beans.Test2;
import beans.Test3;

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션
@Configuration
public class BeanClass {

	//빈 객체 등록하겠단 의미 (xml에선 <bean>으로 객체 등록했었음) 
	//<bean id="test1" class="beans.Test"></bean> 랑 같은 의미 
	@Bean 
	public Test test1() { //메서드 이름이 bean의 이름(주소값)이 된다. 
		Test t1=new Test();
		return t1;
	}
	
	@Bean (name="test2") //name값을 따로 지정할 수도 있음 
	public Test test11() {
		Test t1=new Test();
		return t1;
	}
	
	@Bean
	@Lazy
	public Test2 test3() {
		Test2 t2=new Test2();
		return t2;
	}
	
	@Bean 
	@Scope("protortpe")
	public Test3 test4() {
		Test3 t3=new Test3();
		return t3;
	}
}

 

3) MainClass.java 에서 출력 

("config/beans.xml") 대신 AnnotationConfigApplicationContext클래스를 활용하여 (BeanClass.class)를 사용 

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanClass.class);

package main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import beans.Test;
import beans.Test2;
import beans.Test3;
import config.BeanClass;

public class MainClass {

	public static void main(String[] args) {
	
		//파일형식이 자바이기 때문에 클래스 바뀜
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanClass.class);
		
		Test t1 = ctx.getBean("test1", Test.class);
		System.out.println(t1);

		Test t11 = ctx.getBean("test1", Test.class);
		System.out.println(t11); //자바로 등록을 해도 싱글톤 객체인건 변함 없음 !!! 주소값이 같음 !!!
		
		System.out.println("-------------------------------");
		
	/* Test t12 = ctx.getBean("test11", Test.class); //error발생 ! noBean 이름을 따로 설정해줬기 때문에 존재하지 않는 Bean
		System.out.println(t12);  */

		Test t12 = ctx.getBean("test2", Test.class);
		System.out.println(t12); 
		
		System.out.println("-------------------------------");
		
		Test2 t2 = ctx.getBean("test3", Test2.class);
		System.out.println(t2); 
		
		Test2 t22 = ctx.getBean("test3", Test2.class);
		System.out.println(t22); 
		
		System.out.println("-------------------------------");
		
		Test3 t3 = ctx.getBean("test4", Test3.class);
		System.out.println(t3); 
		
		Test3 t33 = ctx.getBean("test4", Test3.class);
		System.out.println(t33);  //prototype으로 했기 때문에 객체의 주소값 다르다 !
		
		
		
		
		
	}
}

위에 코드 출력 결과

 

 


[ JavaCycle - project ]

 

1) Test.java에 Test, init, destroy 함수 생성 

package beans;

public class Test {

	public Test() {
		System.out.println("test");
	}
	
	public void init() {
		System.out.println("Test init");
	}
	
	public void destroy() {
		System.out.println("Test destroy");
	}
}

 

2) BeanClass.java에 객체 등록 

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;

import beans.Test;


//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션
@Configuration
public class BeanClass {

	//IoC 컨테이너 역할 
	@Bean(initMethod="init", destroyMethod="destroy")
	@Lazy
	public Test test1() {
		return new Test();
	}
	
}

 

3) MainClass.java 

package main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import beans.Test;
import config.BeanClass;

public class MainClass {

	public static void main(String[] args) {
	
		//파일형식이 자바이기 때문에 클래스 바뀜
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanClass.class);

		Test t1 = ctx.getBean("test1", Test.class);
		System.out.println(t1);
		ctx.close();
		
		
		
	}
}

 

 


[ JavaDI - project ]

 

1) Test, Test2, Test3, Data, Data2, Data3 파일 생성

package beans;

public class Test {

	private int d1;
	private String d2;
	private Data d3;
	
	public Test() { }
	
	public Test(int d1, String d2, Data d3) {
		this.d1=d1;
		this.d2=d2;
		this.d3=d3;
	}

	public int getD1() {
		return d1;
	}

	public void setD1(int d1) {
		this.d1 = d1;
	}

	public String getD2() {
		return d2;
	}

	public void setD2(String d2) {
		this.d2 = d2;
	}

	public Data getD3() {
		return d3;
	}

	public void setD3(Data d3) {
		this.d3 = d3;
	}
}
package beans;

public class Test2 {

	private Data2 d1;
	private Data2 d2;
	
	public Data2 getD1() {
		return d1;
	}
	public void setD1(Data2 d1) {
		this.d1 = d1;
	}
	public Data2 getD2() {
		return d2;
	}
	public void setD2(Data2 d2) {
		this.d2 = d2;
	}
	
	
}
package beans;

public class Test3 {

	private Data3 d1;
	private Data3 d2;
	
	public Data3 getD1() {
		return d1;
	}
	public void setD1(Data3 d1) {
		this.d1 = d1;
	}
	public Data3 getD2() {
		return d2;
	}
	public void setD2(Data3 d2) {
		this.d2 = d2;
	}
	
	
}

 

2) BeanClass.java

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import beans.Data;
import beans.Data2;
import beans.Test;
import beans.Test2;

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션
@Configuration
public class BeanClass {

	@Bean
	public Test test1() { //Test 클래스 객체 등록
		//Test t = new Test(10, "spring", new Data());
		return new Test(10, "spring", new Data()); //생성자를 통한 주입 
	}
	
	@Bean
	public Test test2() {
		Test t1=new Test();
		t1.setD1(10);
		t1.setD2("spring");
		t1.setD3(new Data());
		
		return t1;
	}
	
	@Bean
	public Data2 data1() { //Test2 클래스 객체 등록  Test2 는 Data 객체가 존재해서 이런식으로 Data 등록해줘야 함
		return new Data2();
	}
	
	@Bean
	public Data2 data2() {
		return new Data2();
	}
	
	@Bean
	public Test2 test3() { 
		return new Test2();
	}
	
	
	
}

3) MainClass.java 

package main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import beans.Test;
import beans.Test2;
import config.BeanClass;

public class MainClass {

	public static void main(String[] args) {
	
		//파일형식이 자바이기 때문에 클래스 바뀜
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanClass.class);
		
		Test t1 = ctx.getBean("test1", Test.class);
		System.out.println(t1.getD1());
		System.out.println(t1.getD2());
		System.out.println(t1.getD3());
		
		System.out.println("---------------------------");
		
		Test t2 = ctx.getBean("test2", Test.class);
		System.out.println(t2.getD1());
		System.out.println(t2.getD2());
		System.out.println(t2.getD3());
		
		System.out.println("---------------------------");
		
		Test2 t3 = ctx.getBean("test3", Test2.class);
		System.out.println(t3.getD1());
		System.out.println(t3.getD2());
		
		
	}
}

 

 

 


[ JavaDI - project ]

 

1) Test, Test2, Test3, Data, Data2, Data3, Data4 파일 생성

package beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Test {

	private int d1;
	private Data d2;
	
	@Autowired //자동주입이라는 뜻 (타입을 통해 bean객체를 자동으로 주입한다)
	private Data d3;
	
	@Autowired
	@Qualifier("obj1")
	private Data2 d4;
	
	@Autowired
	@Qualifier("obj2")
	private Data2 d5;

	public int getD1() {
		return d1;
	}

	public void setD1(int d1) {
		this.d1 = d1;
	}

	public Data getD2() {
		return d2;
	}

	public void setD2(Data d2) {
		this.d2 = d2;
	}

	public Data getD3() {
		return d3;
	}

	public void setD3(Data d3) {
		this.d3 = d3;
	}

	public Data2 getD4() {
		return d4;
	}

	public void setD4(Data2 d4) {
		this.d4 = d4;
	}

	public Data2 getD5() {
		return d5;
	}

	public void setD5(Data2 d5) {
		this.d5 = d5;
	}
}
package beans;

import org.springframework.beans.factory.annotation.Value;

public class Test2 {
	
	private int d1;
	private String d2;
	private Data3 d3;
	private Data4 d4;
	
	public Test2() { }
	
	public Test2(@Value("1") int d1, @Value("spring")String d2, Data3 d3, Data4 d4) {
		this.d1=d1;
		this.d2=d2;
		this.d3=d3;
		this.d4=d4;
	}
	
	public int getD1() {
		return d1;
	}
	public void setD1(int d1) {
		this.d1 = d1;
	}
	public String getD2() {
		return d2;
	}
	public void setD2(String d2) {
		this.d2 = d2;
	}
	public Data3 getD3() {
		return d3;
	}
	public void setD3(Data3 d3) {
		this.d3 = d3;
	}
	public Data4 getD4() {
		return d4;
	}
	public void setD4(Data4 d4) {
		this.d4 = d4;
	}
}

 

2) BeanClass.java

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import beans.Data;
import beans.Data2;
import beans.Test;

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션
@Configuration
public class BeanClass {

	@Bean
	public Test test1() {
		return new Test(); //객체 반환 받음
	}
	
	@Bean
	public Data data1() {
		return new Data(); //객체 반환 받음
	}
	
	///////// qualifier이름 설정한거랑 똑같은 이름으로 메서드를 설정해야 자동주입된다.
	@Bean 
	public Data2 obj1() {
		return new Data2();
	}
	
	@Bean 
	public Data2 obj2() {
		return new Data2();
	}
	
}

3) MainClass.java

package main;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import beans.Test;
import beans.Test2;
import config.BeanClass;

public class MainClass {

	public static void main(String[] args) {
	
		//파일형식이 자바이기 때문에 클래스 바뀜
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanClass.class);
		
		Test t = ctx.getBean("test1",Test.class);
		System.out.println(t.getD3());
		System.out.println(t.getD4());
		System.out.println(t.getD5());
		
		Test2 t2 = ctx.getBean("test2",Test2.class);
		System.out.println(t2.getD3());
		System.out.println(t2.getD4());

		
	}
}

 

 


[ Component - project ]

1) 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>kr.bit</groupId>
	<artifactId>Spring1</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<!-- xml에서 사용할 속성들 -->
	<properties>
		<!-- 자바 버전 -->
		<java-version>1.8</java-version>
		<!-- 스프링 버전 -->
		<org.springframework-version>6.0.11</org.springframework-version>
		<!--<org.springframework-version>4.3.25.RELEASE</org.springframework-version> -->
		<org.slf4j-version>1.7.26</org.slf4j-version>
		<ch.qos.logback-version>1.2.3</ch.qos.logback-version>
	</properties>

	<!-- 프로젝트에서 사용할 라이브러리 정보 -->
	<dependencies>
		<!-- spring context -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${org.springframework-version}</version>
		</dependency>
		<!-- slf4j -->
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${org.slf4j-version}</version>
		</dependency>
		<!-- logback -->
		<dependency>
			<groupId>ch.qos.logback</groupId>
			<artifactId>logback-classic</artifactId>
			<version>${ch.qos.logback-version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-api</artifactId>
				</exclusion>
			</exclusions>
			<scope>runtime</scope>
		</dependency>
		
        <!-- 추가 된 내용 -->
		<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
      <dependency>
          <groupId>javax.annotation</groupId>
          <artifactId>javax.annotation-api</artifactId>
          <version>1.3.2</version>
      </dependency>
      
	</dependencies>
</project>

 

2) Test, Test2는 비워두고 Test3, Test4, Test5는 코드 작성 @Component(=bean을 따로 등록하지 않아도 자동으로 등록한다.)를 활용하여 작성

package beans2;

import org.springframework.stereotype.Component;

@Component
//bean을 따로 등록하지 않아도 자동으로 등록된다 
public class Test3 {

	
}
package beans2;

import org.springframework.stereotype.Component;

@Component("component4") //이름은 마음대로 설정 
public class Test4 {

}
package beans3;

import org.springframework.stereotype.Component;

@Component
public class Test5 {

}

 

3) beans.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.xsd">
	                    
	          
	<!-- beans2와 beans3 package에서 component가 있는지 scan(=확인)하겠단 의미 -->
	<!-- <bean>으로 등록하는 대신 이렇게 사용하는 거임 = 일종의 bean 등록 하는 방법 ! -->
	<!-- 지정된 패키지 않에 있는 Bean클래스들의 어노테이션을 분석한다 -->
	<context:component-scan base-package="beans2"></context:component-scan>
	<context:component-scan base-package="beans3"></context:component-scan>   
	
	<bean class="beans.Test"></bean>
	
	<bean class="beans.Test2" id="test2"></bean>
	<bean class="beans.Test2" id="test22"></bean>  
	
	<bean class="beans2.Test4" id="test4"></bean>
	
</beans>

 

4) MainClass.java

package main;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import beans.Test;
import beans.Test2;
import beans2.Test3;
import beans2.Test4;
import beans3.Test5;

public class MainClass {

	public static void main(String[] args) {
	
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("config/beans.xml");

		Test t1=ctx.getBean(Test.class);
		System.out.println(t1);  //ID값 안 적어도 객체 주소 값 출력 되긴 함 
		
		Test2 t2=ctx.getBean("test2", Test2.class);
		System.out.println(t2);  //밑에꺼랑 다른 객체 주소 값 = 싱글톤 아님 (ID값이 다르니깐 ! 당연한 소리 !)
		
		Test2 t22=ctx.getBean("test22", Test2.class);
		System.out.println(t22);  //위에꺼랑 다른 객체 주소 값 = 싱글톤 아님 (ID값이 같아야지 ! 싱글톤임 !)
		
		Test3 t3=ctx.getBean(Test3.class);
		System.out.println(t3);  //ID값 안 적어도 객체 주소 값 출력 되긴 함 
		
		Test4 t4=ctx.getBean("component4", Test4.class); 
		System.out.println(t4); //이름을 설정한 경우 ID값이 됨
		
		Test4 t44=ctx.getBean("test4", Test4.class); 
		System.out.println(t44); 
		
		Test5 t5=ctx.getBean(Test5.class); 
		System.out.println(t5); 
		
	}
}

위에 코드 출력 결과

 

5) BeanClass.java

package config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import beans.Test;
import beans.Test2;
import beans2.Test3;

//현재 자바 파일이 빈 등록을 하기위한(객체등록) 자바파일임을 알리는 @어노테이션
@Configuration
//@ComponentScan어노테이션이 있는 beans2, beans3 패키지 검사(체크) 한다. - 어노테이션이 있는지 확인 (@component, @repository, @controller, @service) ...
@ComponentScan(basePackages = "beans2")
@ComponentScan(basePackages = "beans3")
public class BeanClass {

	@Bean
	public Test test1() {
		return new Test();
	}
	
	@Bean
	public Test2 test2() {
		return new Test2();
	}
	
	@Bean
	public Test3 test3() {
		return new Test3();
	}
	
}

 

 

 

 

 


https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowire.html

 

Autowire (Spring Framework 6.1.6 API)

Enumeration determining autowiring status: that is, whether a bean should have its dependencies automatically injected by the Spring container using setter injection. This is a core concept in Spring DI. Available for use in annotation-based configurations

docs.spring.io

 

728x90