Spring Framework

@Autowired (1)

issell 2019. 5. 26. 19:20

@Autowired 

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

 

Autowired (Spring Framework 5.1.7.RELEASE API)

Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities. This is an alternative to the JSR-330 Inject annotation, adding required-vs-optional semantics. Only one constructor (at max) of any

docs.spring.io

bean의 의존주입 시 setter에 의한 등록이 아닌 

@Autowired를 사용하여 bean의 property를 자동 등록해주는 어노테이션이다.

<bean>을 매번 주입하는 방식보다 코드가 훨씬 간결해진다.

 

특정 bean의 property 주입을 xml로 표현하자면 다음과 같다. 여기서는 Service 내의 Dao 주입을 예시로 들었다.

<bean id = "myDao" class = "test.MyDao"/> <!-- dao bean 생성 -->
<bean id = "myService" class = "test.MyService">
	<property name="dao" ref = "myDao"/> <!-- service bean에 dao 프로퍼티 주입 -->
</bean>

 

순수한 자바로 표현하자면 다음과 같다.

public class MyService {
  private MyDao dao;
  public void setDao(MyDao dao){
      this.dao = dao;
  }
}



// Service 생성부
MyDao myDao = new MyDao();
MyService myService = new MyService();
myService.setDao(myDao);

 

이를 @Autowired로 적용해보자

@Repository
public class MyDao {
	...
}

@Service
public class MyService {
	
	@Autowired 
	private MyDao dao; // 자동으로 MyDao 타입의 Bean이 주입된다.
    
    ...
	
}

 

다음과 같이 표현할 수도 있다. 

@Repository("my_dao")
public class MyDao {
	...
}

@Service
public class MyService {
	
	@Autowired 
	private MyDao my_dao; // 자동으로 my_dao로 매핑된 MyDao 타입의 Bean이 주입된다.
    
    ...
	
}

 

service 측에서 dao를 가질 때 setter 의 호출이나 property injection 없이도 단순히 @Autowired를 사용하여 자동으로 연동할 수 있다.

여기서 Autowired 란 '자동으로 연결하다'라는 의미를 가지고 있다는 걸 안다면 이해가 쉬울 것이다.

하지만 @Autowired로 연동될 Dao 객체는 반드시 서버의 loading time 중에 생성되어야 하는 주의점이 있다.

어쩌면 당연한 이야기가 될 수 있는데, 알다시피 bean을 주입하는 시점에서 bean은 존재해야하기때문이다!

위의 소스코드에서 Dao bean은 wired 되기 전 생성되어있어야 하는데, 이는 크게 두 가지 방법으로 나뉜다.

방법1. xml에 <bean>으로 등록

방법2. Dao 클래스 정의 시 @Component 혹은 @Bean 선언

Controller 클래스에는 이 @Autowired를 사용하여 다양한 객체를 얻어올 수 있다. (Request, Session, Application 등)

 

HomeController 클래스

package com.test.ch09;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;


@Controller
public class HomeController {

	@Autowired
	private HttpServletRequest request;
	
	@Autowired
	private HttpSession session;
	
	@Autowired
	private ServletContext application;
	
	@RequestMapping("/")
	public String home() {
		request.setAttribute("attr1", "request.attr1");
		session.setAttribute("attr2", "session.attr2");
		application.setAttribute("attr3", "application.attr3");
		System.out.println(session.getAttribute("attr2"));
		return "home";
	}
}

 

home.jsp

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

	attr1 : ${ requestScope.attr1 }<br>
	attr2 : ${ sessionScope.attr2 }<br>
	attr3 : ${ applicationScope.attr3 }<br>

</body>
</html>

 

브라우저 실행 결과

 


@Autowired 를 사용하기 위해서는..

@Component를 자동으로 생성하는 Auto-detecting의 경우는 @Autowired 어노테이션도 자동으로 등록되기때문에 사용가능하다.  servlet-context.xml 을 확인해보자.

<context:component-scan base-package="com.test.*" /> <!-- 이 경우 아무 설정 안해도 된다. -->

 

하지만 property 주입 등의 이유로 수동으로 컴포넌트를 등록하는 경우는 servlet-context.xml에 다음과 같은 명령을 추가한다.

 <context:annotation-config/>