먼저 DAL에 클래스를 먼저 살펴보겠습니다.
public class DAL {
public
DAL()
{
System.Diagnostics.Debug.WriteLine("데이터 생성자
호출");
}
~DAL()
{
System.Diagnostics.Debug.WriteLine("데이터 소멸자
호출");
}
public void
ExcuteDal1()
{
System.Diagnostics.Debug.WriteLine("데이터 Excute1()
호출");
}
public void
ExcuteDal2()
{
System.Diagnostics.Debug.WriteLine("데이터 Excute2()
호출");
}
public void
ExcuteDal3()
{
System.Diagnostics.Debug.WriteLine("데이터 Excute3()
호출");
} } |
그럼 이제 BLL클래스를 만들어 보겠습니다. 2가지 방식으로 BLL 클래스를 만들어 보도록 하겠습니다.
1번째로 DAL클래스를 멤버변수로 가지고 있을 경우입니다.
public class BLL {
private DAL dal = new DAL();
//public DAL
Dal //{ // get { return dal;
} // set { dal = value;
} //}
{
System.Diagnostics.Debug.WriteLine("비지니스 생성자
호출");
}
~BLL()
{
System.Diagnostics.Debug.WriteLine("비지니스 소멸자
호출");
}
public void
ExcuteBll1()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute1()
호출");
dal.ExcuteDal1();
dal.ExcuteDal2();
}
public void
ExcuteBll2()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute2()
호출");
dal.ExcuteDal2();
dal.ExcuteDal3();
} } |
2번째로는 BLL클래스의 메소드 안에 DAL클래스를 사용하는 경우입니다.
public class BLL {
public
BLL()
{
System.Diagnostics.Debug.WriteLine("비지니스 생성자
호출");
}
~BLL()
{
System.Diagnostics.Debug.WriteLine("비지니스 소멸자
호출");
}
public void
ExcuteBll1()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute1()
호출");
DAL dal = new DAL();
dal.ExcuteDal1();
dal.ExcuteDal2();
}
public void
ExcuteBll2()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute2()
호출");
DAL dal = new DAL();
dal.ExcuteDal2();
dal.ExcuteDal3();
} } |
Spring에서 DI의 기능을 사용하기 위한 일반적인 방법은 생성자(Constructor Injection)나 프로퍼티(Setter Injection)를 이용해서 주입시키는 방법으로 바로 1번에 해당하는 구조입니다. 1번 구조로 DI기능을 이용해서 BLL 객체를 만들어보겠습니다. 1번 구조에서 new키워드를 사용한 부분을 제거하고 주석 부분을 해제한 후에 DI기능으로 DAL 객체를 생성해보겠습니다. 아래는 환경설정 파일과 컨테이너에서 BLL 객체를 가져오는 코드입니다.
<object
id="dal" type="ObjectLifeCycle.DAL,
ObjectLifeCycle" singleton="false"/> <object
id="bll" type="ObjectLifeCycle.BLL,
ObjectLifeCycle" singleton="false"> <property
name="Dal" ref="dal"
/> </object> |
IApplicationContext ctx = ContextRegistry.GetContext(); BLL bll = ctx["bll"] as BLL; bll.ExcuteBll1(); //bll.Dal =
null; //GC.Collect(); bll.ExcuteBll2(); |
1번 구조에서는 위에서 말했듯이 DAL 생성자가 호출되고 BLL 생성자가 호출됩니다. 반면에 컨테이너에서 BLL 객체를 가져오면 BLL 생성자가 호출이 되고 DI기능에 의해서 DAL 생성자가 호출됩니다. 어느것이 먼저 생성되느냐에 차이점만 있습니다. 처음에 DI기능을 이용하면 프로퍼티를 호출하는 시점에 DAL 객체를 가져오는 줄 알았습니다. 하지만 BLL 객체를 생성한 이후에 바로 DI기능에 의해서 DAL 객체가 생성이 됩니다. 또한 이 구조에서는 DAL객체를 환경설정 파일에서 prototype으로 생성했지만 BLL 객체가 소멸되기 전까지 DAL 객체는 소멸이 되면 안됩니다. 왜냐하면 이전 포스트에서 가비지 수집기에 객체를 수집할 수 있는 방법으로 null을 대입해주는 방법이 있다고 하였고 위의 예에서 주석 부분을 제거하고 실행하면 예외가 발생하기 때문입니다. bll.ExcuteBll2()이 실행되기 직전에 가비지 수집기에 의해 DAL 객체가 소멸되었기 때문입니다.
그렇다면 바로 2번 구조처럼 BLL 클래스에 종속되지 않으면서 필요한 경우에 DAL 객체를 만들어서 사용하는 방법은 없을까요? 그 방법은 바로 메소드(Method Injection)로 주입해주는 방식입니다. 메소드로 주입해주는 방법은 두 가지 있으며 한 가지는 IObjectFactoryAware를 상속받는 방법과 Lookup Method Injection 방법입니다. IObjectFactoryAware 방법은 Spring 문서에서 권장을 하지 않기 때문에 두 번째 방식으로 구현해보겠습니다.
<object
id="dal" type="ObjectLifeCycle.DAL,
ObjectLifeCycle" singleton="false"/> <object
id="bll" type="ObjectLifeCycle.BLL,
ObjectLifeCycle" singleton="false"> <lookup-method
name="Dal" object="dal"
/> </object> |
public abstract class BLL {
protected abstract DAL
Dal();
public
BLL()
{
System.Diagnostics.Debug.WriteLine("비지니스 생성자
호출");
}
~BLL()
{
System.Diagnostics.Debug.WriteLine("비지니스 소멸자
호출");
}
public void
ExcuteBll1()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute1()
호출");
DAL dal =
Dal();
dal.ExcuteDal1();
dal.ExcuteDal2();
}
public void
ExcuteBll2()
{
System.Diagnostics.Debug.WriteLine("비지니스 Excute2()
호출");
DAL dal =
Dal();
dal.ExcuteDal2();
dal.ExcuteDal3();
} } |
2번에 걸쳐 객체의 생명주기에 대해서 알아보았습니다. 객체에 생명주기에 관심이 없으신 분들은 객체 하나 만드는데 너무 복잡한거 아니냐 가비지 수집기가 있는데 왜 그런거에 관심을 가져야 하느냐 반문 하실 수 있습니다. 하지만 진짜 프로그래머라면 어떻게 하면 좀 더 효율적으로 프로그래밍을 할 것인가에 대한 고민은 밥을 먹는것과 같은거 아닐까요?
'GET > FrameWork' 카테고리의 다른 글
방랑이가 생각하는 Spring.NET... (0) | 2009.10.06 |
---|---|
Spring.NET - 레퍼런스 문서 한글화 사이트.. (0) | 2009.09.30 |
객체의 생명주기 (0) | 2009.09.30 |
Spring.NET 생명 주기 (0) | 2009.09.30 |
Hands-on Labs for EL 4.1 and Unity 1.2 (0) | 2009.09.29 |