class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
ConnectionMaker connectionMaker = new DConnectionMaker();
UserDao dao = new UserDao(connectionMaker);
....
}
}
따라서 이 두가지 기능 분리해야 할 필요가 있다.
팩토리
란 객체의 생성방법을 결정하고 그렇게 만들어진 객체를 돌려주는 역할을 하는 오브젝트를 말한다.public class DaoFactory{
public UserDao userDao() {
ConnectionMaker connectionMaker = new DConnectionMaker();
UserDao dao = new UserDao(connectionMaker);
return dao;
}
}
class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
UserDao dao = new DaoFactory.userDao();
....
}
}
빈(bean)
이라고 부른다. 동시에 스프링 빈은 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리키는 말이다. 빈 팩토리(bean factory)
라고 부른다. 보통 빈 팩토리보다는 이를 좀 더 확장한 애플리케이션 컨텍스트(applcation context)
를 주로 사용한다.@Configuration
public class DaoFactory {
@Bean
public UserDao userDao() {
return new UserDao(conntetionMaker());
}
@Bean
public ConnetionMaker connectionMaker() {
return new ConnectionMaker();
}
}
class UserDaoTest {
public static void main(String[] args)
throws ClassNotFoundException, SQLException {
ApplicationContext context =
new AnnotationConfigApplicationContext(DaoFactory.class);
UserDao userDao = context.getBean("userDao", UserDao.class);
}
}
빈 또는 빈 오브젝트는 스프링이 IoC방식으로 관리하는 오브젝트라는 뜻이다. 스프링에서 사용하는 모든 오브젝트가 빈이 아니라 그중에서도 스프링이 직접 그 생성과 제어를 담당하는 오브젝트만을 빈이라고 부른다.
스프링의 IoC를 담당하는 핵심 컨테이너를 가르킨다. 빈 등록, 생성, 조회, 반환하고 그외에 부가적인 빈을 관리하는 기능을 담당한다. 보통은 빈 팩토리를 바로 사용하지 않고 이를 확장한 애플리케이션 컨텍스트를 이용한다.
빈 팩토리를 확장한 IoC 컨테이너이다. 빈을 관리하는 기본적인 기능은 빈 팩토리와 동일하고 여기에 스프링이 제공하는 각종 부가 서비스를 추가로 제공한다.
스프링의 설정정보란 애플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위해 사용하는 메타정보를 말한다.
컨테이너에 어떤 기능을 세팅하거나 조겅하는 경우에도 사용하지만 주로 IoC 컨테이너에 의해 관리되는 애플리케이션 오브젝트를 생성하고 구성할 때 사용된다.
IoC 방식으로 빈을 관리한다는 의미에서 애플리케이션 컨텍스트나 빈 팩토리를 컨테이너 또는 IoC 컨테이너라고도 한다. 후자는 주로 빈 팩토리 관점에서 이야기하는 것이고, 그냥 컨테이너 또는 스프링 컨테이너라고 할 때는 애플리케이션 컨텍스트를 가리키는 것이라고 보면 된다.
IoC컨테이너, 애플리케이션 컨텍스트를 포함해서 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용한다.
오브젝트의 동일성과 동등성
자바에서는 두 개의 오브젝트가 같은가라는 말을 주의해서 써야한다.
두개의 오브젝트가 완전히 같은 동일한 오브젝트라고 말하는 것과 동일한 정보를 담고 있는 오브젝트라고 말하는 것은 분명한 차이가 있다.
전자를동일성 비교(==)
, 후자를동등성 비교(equals())
하고 한다.
동일성 (Identity) : 두 객체가 완전히 같을 경우
동등성 (Equality) : 두 객체가 같은 정보를 같고 있을 경우
DaoFactory factory = new DaoFactory();
// 두 userDao가 다르다.
UserDao userDao1 = factory.userDao();
UserDao userDao2 = factory.userDao();
ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
// 두 userDao가 같다.
UserDao userDao3 = context.getBean("userDao", UserDao.class);
UserDao userDao4 = context.getBean("userDao", UserDao.class);
싱글톤
으로 만들기 때문이다.스프링이 주로 적용되는 대상이 자바 엔터프라이즈 기술을 사용하는 서버환경이기 때문이다. 클라이언트 요청이 올때마다 새로운 오브젝트를 만든다고 가정해보자.
요청 한번에 10개의 오브젝트를 만들어야하고, 초당 1000개의 요청이 들어온다면 초당 10000개의 오브젝트를 만들어야한다.
아무리 자바의 오브젝트 생성과 GC의 성능이 좋아졌다고 한들 이렇게 부하가 걸리면 서버가 감당하기 힘들다.
public class UserDao{
private static UserDao INSTANCE;
...
private UserDao(ConnetionMaker connetionMaker) {
this.connetionMaker = connetionMaker;
}
public static synchronized UserDao getInstance() {
if(INSTANCE == null) {
INSTANCE == new UserDao(...);
}
return INSTANCE;
}
}
그리고 다음과 같은 일반적인 문제들이 있다.
자바의 기본적인 싱글톤 패턴의 구현 방식에는 여러가지 단점이 있기에 스프링은 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공한다. 그것이 바로 싱글톤 레지스트리(singleton registry)
다.
싱글톤 레지스트리는 스태틱 메소드와 private 생성자를 사용해야하는 비정상적인 클래스가 아니라 평범한 자바 클래스를 싱글톤으로 활용하게 해준다.
무상태(stateless)
방식으로 만들어져야 한다.스코프(scope)
라고 한다. 스프링 빈의 기본 스코프는 싱글톤이다.