Day088

RISK_TAKER·2023년 6월 7일
0

SpringBeanProject

Bean이란?

  • 스프링 컨테이너에서 메모리에 등록해놓고 관리하는 객체
  • 자바 클래스로 만든 객체
  • Application에서 사용되는 객체
  • IOC 컨테이너가 관리한다.

Spring의 대표적인 특성 3가지

  1. IOC(Inversion of Control)
    제어의 역전, 만들고 등록한 Bean들을 관리(IOC 컨테이너)

  2. DI(Dependency Injection)
    의존성 주입

  3. AOP(Aspect Oriented Programming)
    관점지향 프로그래밍

root-context.xml에 Bean을 등록하는 방법

<bean id="sampleBean1" class="com.app.beans.SampleBean1"></bean>

<bean id="sampleBean2" class="com.app.beans.SampleBean2"></bean>

<!-- lazy-init 기본 : 서버 시작 시, xml 로딩 과정에서 Bean 생성
	lazy-init true : 실제 Bean 접근해서 사용하려고 할때 생성 -->	
<bean id="sampleBean3" class="com.app.beans.SampleBean3" lazy-init="true" />
	
<!-- scope 기본 : 싱글톤 객체(전체에서 1개만) -->
<!-- scope prototype : 일반적인 객체로 활용 (new 생성) -->
<!-- 그냥 new로 생성하면 되기때문에 잘 쓰이지는 않는다. -->
<bean id="sampleBean4" class="com.app.beans.SampleBean4" scope="prototype" />
	
<bean id="initDestroyBean" class="com.app.beans.InitDestroyBean" init-method="bean_init" destroy-method="bean_destory"/>
	
<bean id="containerBean1" class="com.app.beans.ContainerBean"/>
	
<bean id="containerBean2" class="com.app.beans.ContainerBean" >
	<!-- 생성자를 세팅하는 부분 -->
	<constructor-arg value="xml에서 주입한 이름" />
</bean>
	
<bean id="fieldBean" class="com.app.beans.FieldBean">
	<constructor-arg value="xml 주입 데이터" />
</bean>
	
<bean id="containerBean3" class="com.app.beans.ContainerBean" >
	<!-- 위에서 만든 fieldBean을 매칭 -->
	<constructor-arg ref="fieldBean" />
</bean>

root-context.xml에 등록해둔 Bean객체를 가져오고 사용하는 방법

Case1. BeanFactoryAware를 구현한다.

//MainController.java
@Controller
public class MainController implements BeanFactoryAware{
	
	SampleBean1 sb1;

	@RequestMapping("/checkBean")
	public String checkBean() {
				
		SampleBean1 bean1 = new SampleBean1();
		System.out.println(bean1);
		
		SampleBean1 bean2 = new SampleBean1();
		System.out.println(bean1);
				
		return "checkBean";
	}
	
	@RequestMapping("/xmlBean1")
	public String xmlBean1() {
		
		//sampleBean1을 가져다 쓰고 싶은 경우SampleBean1
		System.out.println("/xmlBean1 : " + sb1);
		
		return "checkBean";
	}
	@RequestMapping("/xmlBean2")
	public String xmlBean2() {
		
		//sampleBean1을 가져다 쓰고 싶은 경우SampleBean1
		System.out.println("/xmlBean2 : " + sb1);

		
		return "checkBean";
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		// TODO Auto-generated method stub
		
		//등록한 bean을 가져오는 방법
		sb1 = (SampleBean1)beanFactory.getBean("sampleBean1");
		
		System.out.println("setBeanFactory");
		System.out.println(sb1);
		
	}
}

Case2. ApplicationContext를 사용하는 방법

//BeanController.java
@Controller
public class BeanController {

	@Autowired
	ApplicationContext applicationContext;
	
//	@Autowired
//	BeanFactory beanFactory;
	
	@RequestMapping("/sb1")
	public String sb1() {
		
		SampleBean1  sb1 = (SampleBean1)applicationContext.getBean("sampleBean1");
		System.out.println("/sb1 - " + sb1);
		
		return "checkBean";
	}
	@RequestMapping("/sb1_2")
	public String sb1_2() {
		
		SampleBean1 sb1 = (SampleBean1)applicationContext.getBean("sampleBean1");
		System.out.println("/sb1_2 - " + sb1);
		
		return "checkBean";
	}
	@RequestMapping("/sb2")
	public String sb2() {
		
		SampleBean2  sb = (SampleBean2)applicationContext.getBean("sampleBean2");
		System.out.println("/sb2 - " + sb);
		
		return "checkBean";
	}
	@RequestMapping("/sb2_2")
	public String sb2_2() {
		
		SampleBean2  sb = (SampleBean2)applicationContext.getBean("sampleBean2");
		System.out.println("/sb2_2 - " + sb);
		
		return "checkBean";
	}
	@RequestMapping("/sb3")
	public String sb3() {
		
		SampleBean3  sb = (SampleBean3)applicationContext.getBean("sampleBean3");
		System.out.println("/sb3 - " + sb);
		sb.setCheck(100);
		System.out.println(sb.getCheck());
		
		return "checkBean";
	}
	@RequestMapping("/sb3_2")
	public String sb3_2() {
		
		SampleBean3  sb = (SampleBean3)applicationContext.getBean("sampleBean3");
		System.out.println("/sb3_2 - " + sb);
		System.out.println(sb.getCheck());
		
		return "checkBean";
	}
	@RequestMapping("/sb4")
	public String sb4() {
		
		SampleBean4  sb = (SampleBean4)applicationContext.getBean("sampleBean4");
		System.out.println("/sb4 - " + sb);
		
		return "checkBean";
	}
	@RequestMapping("/sb4_2")
	public String sb4_2() {
		
		SampleBean4  sb = (SampleBean4)applicationContext.getBean("sampleBean4");
		System.out.println("/sb4_2 - " + sb);
		
		return "checkBean";
	}
}

DIConcept, 인터페이스 다형성 개념을 적용

  • 인터페이스를 구현한 클래스의 객체는 인터페이스 타입으로 담을 수 있기 때문에 변경 사항이 생기면 쉽게 고칠 수가 있다.
interface CoffeeMachine {
	
	public int getCoffeeShot();
}

class CoffeeShop {
	
	CoffeeMachine coffeeMachine;
	
	public CoffeeShop(CoffeeMachine coffeeMachine) { //4. 변경된 타입에 맞게 생성자 수정
		this.coffeeMachine = coffeeMachine;
	}
	
	public int createCoffee() {
		//커피 제조에 필요한 과정
		//컵 꺼내기
		//물 따르기
		//샷 뽑기
		int shot = coffeeMachine.getCoffeeShot(); //5. 커피샷 만드는 과정 수정(변수명 변경 + 메소드명 변경)
		//컵에다가 샷 붓고..
		//뚜껑 닫고
		
		return 1; //커피 한잔
		
	}
}

class CoffeeMachinePrimium implements CoffeeMachine{
	String brand;
	String name;

	@Override
	public int getCoffeeShot() {
		//커피 뽑는 과정... 머신만의 특성
		//프리미엄 과정... 고급 과정
		return 1;
	}
}

class CoffeeMachineNormal implements CoffeeMachine {
	String brand;
	String name;
	
	@Override
	public int getCoffeeShot() {
		//커피 뽑는 과정..머신만의 특성..
		return 1; //에스프레소 1샷
	}
}
CoffeeMachineNormal cm = new CoffeeMachineNormal();
CoffeeMachinePrimium cmp = new CoffeeMachinePrimium();
CoffeeShop myShop = new CoffeeShop(cmp); //인터페이스를 활용하여, 객체(빈)를 주입시키는 과정
		
int resultCoffee = myShop.createCoffee(); //커피 만든다.
System.out.println(resultCoffee); //만든 커피 활용

DI 관련 코드

DIController.java

@Controller
public class DIController {

	@Autowired
	ApplicationContext applicationContext;
	
	@RequestMapping("/beanDi1")
	public String beanDi1() {
		
		ContainerBean cb1 = (ContainerBean)applicationContext.getBean("containerBean1");
		ContainerBean cb2 = (ContainerBean)applicationContext.getBean("containerBean2");
		
		System.out.println("/beanDi1");
		System.out.println("cb1.name - " + cb1.getName());
		System.out.println("cb2.name - " + cb2.getName());
		
		return "checkBean"; //화면쪽을 볼 게 아니어서 이전 것 그냥 가져다 쓰기
	}
	
	@RequestMapping("/beanDi2")
	public String beanDi2() {
	
		ContainerBean cb3 = (ContainerBean)applicationContext.getBean("containerBean3");
		
		System.out.println("/beanDi2");
		System.out.println("cb3.name - " + cb3.getName());
		System.out.println("cb3.fieldBean.data - " + cb3.getFieldBean().getData());
		
		return "checkBean";
	}
}

ContainerBean.java

public class ContainerBean {

	String name;
	FieldBean fieldBean; //객체타입
	
	public ContainerBean() {
		name = "기본이름";
	}
	public ContainerBean(FieldBean fieldBean) {
		this.fieldBean = fieldBean;
	}
	
	public ContainerBean(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public FieldBean getFieldBean() {
		return fieldBean;
	}
	
	public void setFieldBean(FieldBean fieldBean) {
		this.fieldBean = fieldBean;
	}
	
}

FieldBean.java

public class FieldBean {

	String data;
	
	public FieldBean(String data) {
		this.data = data;
	}

	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}
	
}

Spring에서 (싱글톤)Singletone 객체를 사용하는 이유

  • DAO를 통해 DB에 접근을 하는 경우 -> 여러 객체가 한꺼번에 접근을 하는 경우에 충돌이 나는 등의 문제가 발생할 수 있다.
  • 객체가 계속 생성되어 메모리가 낭비되는 문제를 방지하려는 목적도 있다.

0개의 댓글