[스프링] 의존성 주입

Nux·2022년 2월 28일
0
post-thumbnail
post-custom-banner

https://velog.io/@yoonee1126/Day68 보충

의존성 주입 대상

기본자료형 타입

  • 정수, 실수, 불린형, 문자열 등
  • 의존성 주입 시 value 사용
<property name="setter메서드이름" value=""/>

객체타입

  • 스프링컨테이너가 관리하는 객체(빈)
<property name="setter메서드이름" ref="빈아이디"/>

Collection타입

  • 기본자료형이나 스프링 컨테이너가 관리하는 객체를 여러개 저장하고 있는 객체
    • 배열, set, list 등
  • 주입 시 setter와 constructor 모두 사용 가능
public class SampleController{
	String[] urls;	// 배열
    Set<MessageService> messageService;	// Set
    List<ExceptionHanlder> exceptionHandlers;	// List
    
    // setter생략
}
<bean id="sampleController" class="com.sample.SampleController">
	<!-- String[] urls -->
	<property name="urls">
    	<array>
        	<value>http://www.naver.com</value>
            <value>http://www.daum.net</value>
        </array>
    </property>
    
    <!-- Set<MessageService> -->
    <property name="messageService">
    	<set>
        	<ref bean="smsMessageService"/>
            <ref bean="emailMessageService"/>
        </set>
    </property>
    
    <!-- List<ExceptionHandler> -->
    <property name="exceptionHandler">
    	<list>
        	<ref bean="runtimeExceptionHandler"/>
            <ref bean="DataAccessExceptionHandler"/>
        </list>
    </property>
</bean>
  • 값 바로 넣기: value
  • 객체 넣기: ref

Map타입

  • 기본 자료형이나 스프링 컨테이너가 관리하고 있는 객체를 key,value쌍으로 여러개 저장하는 객체
public class SampleController{
	Map<String, MessageService> messageServices;
    
    public void setMessageServices(Map<String, MessageService> messageService){
    	this.messageServices = messageServices;
    }
    
    public void execute(String key, String message){
    	MessageService service = messageServices.get(key);
        service.send(message);
    }
}
<bean id="sampleController" class="com.sample.SampleController">
	<property name="messageServices>
    	<map>
        	<entry key="sms" value-ref="smsMessageServiceImple" />
            <entry key="email" value-ref="emailMessageServiceImple" />
            <entry key="app" value-ref="appPushMessageServiceImple" />
        </map>
    </property>
</bean>

xml파일로 의존성 주입

  • src - main - resources - spring 내 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>
  • 파일 상단에 작성

setter를 이용한 주입

1. Service - 업무로직이 구현된 곳
public interface ProductService {

	Product getProductByNo(int no);
	
}

2. Controller
	private UserService userService;
	
	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public String execute(int userNo) {
		User user = userService.getUserByNo(userNo);
		System.out.println("사용자번호: "+user.getNo());
		System.out.println("사용자명: "+user.getName());
		System.out.println("사용자이메일: "+user.getEmail());
		System.out.println("사용자비밀번호: "+user.getPassword());
		
		return "detail.jsp";
	}

property태그 사용

<?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">
       
    1.
	<bean id="userServiceImpl" class="com.sample.service.UserServiceImpl"/>
    
	2.
	<bean id="userController" class="com.sample.controller.UserController">
		<property name="userService" ref="userServiceImpl" />
	</bean>
  
</beans>
<bean id="userServiceImpl" class="com.sample.service.UserServiceImpl"/>
  • UserServiceImpl을 타입으로 갖는 userServiceImple이라는 이름을 가진 객체 생성됨

UserServiceImpl userServiceImpl = new UserServiceImpl();

<bean id="userController" class="com.sample.controller.UserController">
	<property name="userService" ref="userServiceImpl" />
</bean>
  • bean
    • id: 식별자
    • class: 객체 생성할 클래스 전체경로

UserController userController = new UserController();

  • property
    • name: setter메서드 명
    • ref: name에서 지정한 setter에 조립시킬(의존성을 주입할) 다른 객체의 빈 아이디

userController.setUserService(userServiceImpl());

네임스페이스 사용

xmlns:p = "http://www.springframework.org/schema/p"
  • xml 파일 하단의 namespace에서 추가
    • property이므로 p 체크
<bean id="userController" class="com.sample.controller.UserController">
	<property name="userService" ref="userServiceImpl" />
</bean>

아래처럼 변경

<bean id="userController" class="com.sample.controller.UserController"
	p:userService-ref="userServiceImpl"/>

생성자를 이용한 주입

1. Service
public class ProductServiceImpl {
	
	public Product getProductByNo(int no) {
		return new Product(100,"애플워치","애플",650000,610000);
	}
	
}

2. Controller
public class SampleConstructorController {

	private ProductServiceImpl productService;

	public SampleConstructorController(ProductServiceImpl productService) {
		this.productService = productService;
	}
	
	public String execute() {
		Product product = productService.getProductByNo(100);
		User user = userService.getUserByNo(100);
		
		System.out.println(product);
		System.out.println(user);
		
		return null;
	}
	
}

constructor-arg 태그 사용

<?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="productServiceImpl" class="com.sample.service.ProductServiceImpl"/>
	
	<bean id="sampleController" class="com.sample.controller.SampleConstructorController">
		<constructor-arg name="productService" ref="productServiceImpl"/>
	</bean>
    
</bean>
<bean id="productServiceImpl" class="com.sample.service.ProductServiceImpl"/>

ProductServiceImpl productServiceImpl = new ProductServiceImpl();

<bean id="sampleController" class="com.sample.controller.SampleConstructorController">
	<constructor-arg name="productService" ref="productServiceImpl"/>
</bean>
  • name: 매개변수 이름
  • ref: 생성자에 매개변수로 전달할 빈(객체) 아이디

SampleConstructorController sampleController
= new SampleConstructorController(productServiceImpl());

네임스페이스 사용

  • xml 파일 하단의 namespace에서 추가
    • contructor-arg이므로 c체크
<bean id="sampleController" class="com.sample.controller.SampleConstructorController">
	<constructor-arg name="productService" ref="productServiceImpl"/>
</bean>

아래처럼 변경

<bean id="sampleController" class="com.sample.controller.SampleConstructorController" c:productService-ref="productServiceImpl">

Java파일로 의존성 주입

  • @Bean어노테이션을 사용하여 빈 등록
  • 클래스에 @Configuration을 붙이고, 빈으로 등록할 객체에 @Bean을 붙임
@Configuration
public class Config{
	
    @Bean
    public Engine{}
    @Bean
    public Door{}

}

@Component

  • 클래스에 @Component를 붙여서 빈 등록
@Component
public class Car{
	...
}

Component Scan

  • @Component, @Service, @Repository, @Controller가 부착된 클래스를 자동으로 스캔하여 Bean으로 등록

설정파일이 xml일 때

<context:component-scan base-package="경로"/> 
  • base-package경로의 클래스를 스캔하여 빈을 등록
  • exclude-filter/include-filter를 이용해서 원하는 클래스를 스캔대상에서 제외/추가 가능
<context:component-scan base-package="경로">
    <context:exclude-filter type="annotation" 
        expression="경로.제외할어노테이션"/>
    <context:include-filter type="regex" 
        expression="스캔에포함할경로"/>        
</context:component-scan>

설정파일이 자바일 때

  • @Configuration 클래스에 @ComponentScan을 붙여서 적용
@Configuration
@ComponentScan
public class ApplicationConfig{}
post-custom-banner

0개의 댓글