Spring

Spring, ApplicationContext 파일 불러오기 / 클래스간의 의존관계를 관리방법 / Singleton ↔ Prototype 변경

greenyellow-s 2024. 10. 28. 14:00
728x90
반응형
ApplicationContext 파일 불러오기

 

 

ApplicationContext context = new FileSystemXmlApplicationContext("src/applicationContext.xml");

                                            = new ClassPathXmlApplicationContext("applicationContext.xml")

 

파일 위치를 쓰지 않고 파일명만 써도 된다.

 

 

applicationContext.xml에 선언한 bean 불러오기

 

Calc calc2 = (Calc) context.getBean("calcMul");

                  = context.getBean("calcMul", Calc.class);

 

 

applicationContext.xml에서 bean 말고 component로 선언한 경우

@Component(“calcAdd”)

 

원래는 객체명을 쓰는 것이 맞지만 class명과 같다면 없어도 Spring이 알아서 인식한다.

@Component

 

 

 

 


스프링은 각 클래스간의 의존관계를 관리하기 위한 방법

 

 

 

Constructor Injection

 

생성자를 통해서 의존 관계를 연결시키는 것을 말한다.

생성자를 통해서 의존 관계를 연결하기 위해서는 XML 설정 파일에서 요소의 하위요소로 <constructor-arg>를 추가해야 한다

 

1. <value>

2. <index>

3. <type>

4. ref

 

[Foo.java]

public class Foo { 
    private Bar bar;
        public Foo(Bar bar){ 
        this.bar = bar; 
    }
}

 

 

[applicationContext.xml]

<bean id=”foo” class=”Foo”>
	<constructor-arg>
		<ref bean = “bar”>
	<constructor-arg>
</bean>

<bean id=”bar” class=”Bar”/>

 

 

Setter의 경우 property이다.

 

<property name=”bar”> 는 setBar(Bar bar){}를 의미하고

<property ref=”bar”> 는 <bean id=”bar”> 를 의미한다.

 

예시로

<bean id="sungJukInput" class="sample04.SungJukInput">
	<property name="sungJukDTO2" ref="sungJukDTO2"></property>
</bean>

 

sungJukDTO2(name) setter에 <bean id="sungJukDTO2">의 값을 넘겨주겠다 라는 의미이다.

 

 

 

 

 

 


Lombok 활용

 

 

Lombok 추가 Maven, dependency 안에 복사 붙여넣기

 

* Lombok이 설정되어 있지 않기 때문에 Lombok을 실행해서 STS에서도 lombok을 사용하겠다고 설정해야지 사용할 수 있다

 

@RequiredArgsConstructor //생성자
public class MessageBeanImpl implements MessageBean {
	@NonNull //생성자
	private String fruit;
    
	@Setter 
	@Getter
	private int cost, qty;

 

<bean>을 넣을 때 에러가 떨어진다

 

이유 : 기본생성자가 없어서

 

매개변수 생성자를 만들어놓으니까 자동으로 만들던 기본생성자를 자동으로 만들지 않아서 그렇다

 

<bean id="messageBeanImpl" class="sample01.MessageBeanImpl">
	<constructor-arg>
		<value>사과</value>
	</constructor-arg>
</bean>

 

=

MessageBeanImpl a = new MessageBeanImpl(“사과”)

 

위 두개는 같은 의미이다.

 

 

 

 

 


생성자를 통해서 원하는 값을 보내준다.

 

 

1. @Value

 

[simple01.MessageBeamImple.java]

import org.springframework.beans.factory.annotation.Value;
public MessageBeanImpl(@Value("사과") String fruit) {
	this.fruit = fruit;
}

 

[applicationContext.xml]

<context:component-scan base-package="sample01"></context:component-scan>

 

 

 

2. @Autowired

 

의존성 주입(Dependency Injection)을 위해 사용되는 어노테이션이다.

이 어노테이션을 통해 Spring이 관리하는 Bean을 자동으로 주입받을 수 있다.

 

@Autowired가 적용된 필드나 메서드는 Spring 컨테이너가 해당 타입의 Bean을 찾아 자동으로 주입한다. 만약 여러 개의 Bean이 존재할 경우, @Qualifier를 사용해 특정 Bean을 지정할 수 있다.

 

반드시 Bean이 존재해야한다.

 

 

@Autowired 를 사용하지 않고 변수를 선언하면 setter값이 처리가 되지 않고 기본값이 처리된다.

public class SungJukImpl implements SungJuk {
	@Autowired
	private SungJukDTO dto = null;

 

생성된 빈들 중에서 SungJukDTO를 찾아서 자동으로 매핑하라는 의미

 

생성자 이건 Setter 이건 상관없이 SungJukDTO를 찾아서 자동으로 매핑한다.

따라서, 생성자가 없어도 된다.

 

 

 

 

 

 

** 싱글톤

 

bean을 선언하면 기본값인 싱글톤으로 설정된다.

 

싱글톤으로 선언되면 계속 새로 선언해도 앞에꺼를 덮어 씌운다.

<bean id="sungJukDTO2" class="sample04.SungJukDTO2" ></bean>

 

 

즉, 그 다음 데이터를 또 받을 때 dto를 새로 생성하지 않고 처음 생성된 dto주소 그대로 담아져서 간다.

 

 

문제 : dto가 또 만들어 져야되는 상황에서도 싱글톤으로 만드니까 dto가 하나이니까 뒤에 들어온 데이터가 앞에 데이터들을 모두 엎어버린다. 

 

해결방법 :  input과 dto 모두 scope="prototype" 추가해서 dto를 새로 만들 수 있게 설정한다.

 

<bean id="sungJukDTO2" class="sample04.SungJukDTO2" scope="prototype"></bean>

 

 

 

list의 경우

List<SungJukDTO2> list = new ArrayList<>();
<bean id="arrayList" class="java.util.ArrayList"></bean>

 

원래

변경

<util:list id="arrayList" list-class="java.util.ArrayList"/>

 

 

 

728x90
반응형

'Spring' 카테고리의 다른 글

Spring Boot, bean생성 / Lombok 사용  (0) 2024.11.06
Spring Boot, 프로젝트 만들기  (0) 2024.11.06
Spring Boot, 스프링 부트란  (1) 2024.11.05
Spring, 스프링과 JDBC  (0) 2024.10.31
Spring, Spring 이란?  (0) 2024.10.28