빈 생명주기 콜백 시작

객체의 초기화 작업과 종료 작업

실행 코드

/*
	외부 네트워크에 미리 연결하는 객체 생성
	애플리케이션 시작 시 : connect() 호출하여, 연결 맺어두기
	애플리케이션 종료 시 : disConnect() 호출하여, 연결 끊기
*/

package hello.core.lifecycle;
/*
	패키지 : 클래스, 인터페이스 등 자바 소스 파일을 포함하는 디렉토리
	
	hello.core 프로젝트 안에 있는 lifecycle 패키지
*/

public class NetworkClient {
/*
	클래스 정의 (NetworkClient라는 이름을 가진 클래스 정의)

	public : 다른 패키지, 클래스에서 접근할 수 있는 (다른 패키지, 클래스에서 해당 클래스의 메서드 사용 가능)
	class : 클래스를 생성하겠다.
*/

		private String url;
		/*
			멤버 변수 (필드) 생성
			멤버 변수 = 해당 클래스의 인스턴스(객체)가 가지는 데이터 값
							=> 클래스의 상태나 속성을 나타내는 데이터를 저장
			
			private : 다른 패키지, 클래스에서 접근할 수 없는 (NetworkClient 클래스만 사용 가능한 변수)
			String : 문자열 형태의
			url : 변수명
		*/

		**// 객체 생성 ({} 안에 있는 거 먼저 전부 생성)**
		// NetworkClient 클래스 객체로 구현
		public NetworkClient() {
		/*
			생성자 (클래스를 객체화할 때 호출되는 메서드)

			public(접근제어자) : 다른 패키지, 클래스에서 접근할 수 있는
			NetworkClient() : 생성자 메서드 명 (클래스 이름과 같다)
		*/

				System.out.println("생성자 호출, url = " + url);
				/*
					원하는 내용 출력

					System : Java의 기본 라이브러리 (클래스)
									=> 표준 입력, 표준 출력, 에러 출력 등의 기능 제공
					out : System 클래스의 정적 멤버 변수 (필드)
									=> PrintStream 타입의 객체를 참조한다.
									=> private PrintStream out;
					printLn() : PrintStream 클래스의 줄바꿈을 포함한 출력 메서드 (메서드)
									=> 출력할 내용을 인자(파라미터)로 받는다
									=> public PrintStream(content) {

					url : 멤버 변수 url 출력
					
					=> "생성자 호출, url = " + 멤버변수 url
			  */

				connect();
				/*
					메서드 호출

					connect() 메서드 호출
				*/
				
				call("초기화 연결 메세지");
				/*
					메서드 호출
					
					call() 메서드 호출
				*/
		}
	

		// setUrl 메서드 정의
		public void setUrl(String url) {
		/*
			메서드 정의

			public : 다른 패키지, 클래스에서 접근할 수 있는
			void : 반환 값이 없는 (return이 없는)
			setUrl() : 메서드 명
			String url : 인자(파라미터 = url)는 String 타입의 객체를 참조한다.
		*/

				this.url = url;
				/*
					this : 멤버 변수(필드)의 변수명과 인자(파라미터)의 변수명이 같을 경우 멤버변수를 가리킨다.
					url : 멤버 변수인 url (문자열 타입)
					url : 인자인 url (문자열 타입)

					=> 인자로 받은 값이 멤버 변수 값이 된다
				*/
		}
		

		// 서비스 시작 시 호출
		public void connect() {
		/*
			메서드 정의
	
			public : 다른 패키지, 클래스에서 접근할 수 있는
			void : 반환 값이 없는 (return이 없는)
			connect() : 메서드 명
		*/
				System.out.println("connect : " + url);
				/*
					원하는 내용 출력
				*/
		}

		// call 메서드 정의
		public void call(String message) {
		/*
			메서드 정의

			public : 다른 패키지, 클래스에서 접근할 수 있는
			void : 반환 값이 없는 (return이 없는)
			call() : 메서드 명
			String message : String 타입의 객체를 참조하는 message를 파라미터로 받는다.
		*/
				
				System.out.print("call : " + url + "message = " + message);
				/*
					원하는 내용 출력

					url : 멤버 변수 url 출력
							=> 이때, setUrl에서 멤버 변수 url은 setUrl 메서드에서 받은 url로 저장
				*/
		}

		// 서비스 종료시 호출
		public void disconnect() {
		/*
			메서드 정의
			
			public : 다른 패키지, 클래스에서 접근할 수 있는
			void : 반환 값이 없는 (return이 없는)
			disconnect() : 메서드 명
		*/

				System.out.println("close : " + url);
				/*
					원하는 내용 출력

					url : 멤버변수 url 출력
				*/
		}
}

검증 코드

// TEST

public class BeanLifeCycleTest {
/*
	클래스 정의

	public : 다른 패키지, 클래스에서 접근할 수 있는
	class : 클래스이다.
	BeanLifeCycleTest : 클래스명
*/

		@Test
		public void lifeCycleTest() {
		/*
			메서드 정의

			public : 다른 패키지, 클래스에서 접근할 수 있는
			void : 반환 값이 없는
			lifeCycleTest() : 메서드 명
		*/

				ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
				/*
					LifeCycleConfig 클래스의 설정 정보를 파라미터로 받아 ac라는 스프링 컨테이너 생성
						=> 객체화
				*/

				NetworkClient client = ac.getBean(NetworkClient.class);
				/*
					NetworkClient client : client는 NetworkClient 타입의 객체를 참조한다.
													=> String url 변수를 가진다.
					ac : 스프링 컨테이너
					getBean : NetworkClient.class의 빈이 가진 속성값을 얻는다.
													=> NetworkClient.class가 가지는 멤버 변수 값
													=> String url 변수의 값을 가진다.
				*/

				ac.close(); // 스프링 컨테이너 종료
		}

		@Configuration // 수동 빈 등록
		static class LifeCycleConfig {
		/*
			클래스 정의

			static : 중첩 클래스가 외부 클래스의 인스턴스 (멤버 변수)와 독립적이다.
					=> 외부 클래스의 정적 멤버 변수에 접근 가능핟.
		*/

				@Bean // 빈 정의
				public NetworkClient networkClient() {
				/*
					생성자 (클래스를 객체화)

					public : 다른 패키지, 클래스에서 접근할 수 있는
					NetworkClient networkClient() : NetworkClient 타입의 객체를 참조하는 networkCleint 객체
																				= networkClient 빈으로 등록
				*/

				**// 객체 생성**
				NetworkClient networkClient = new NetworkClient();
				/*
					클래스의 인스턴스를 생성하여 변수에 할당
					=> 변수는 새로 생성된 NetworkClient 객체를 참조

					NetworkClient networkClient : NetworkClient타입의 객체를 참조하는 networkClient
					new : 새로운 인스턴스 생성
					NetworkClient() : NetworkCleint() 생성자 = NetworkClient 타입의 객체 생성

					=> networkClient는 NetworkClient 클래스의 모든 멤버변수와 메서드를 참조한다
				*/

				**// 초기화 : 값 주입**
				networkClient.setUrl("<http://hello-spring.dev>");
				/*
					setUrl()메서드 활용

					setUrl(String url) {
							=> 문자열 타입의 데이터를 입력받고, url 변수에 담는다.
							=> 파라미터 url = "<http://hello-spring.dev>"
					this.url = url
							=> 멤버 변수 url = 파라미터 url
							=> 멤버 변수 url = "<http://hello-spring.dev>"
				*/

				return networkClient;
				/*
					값을 반환한다

					newtworkCliet = 
							System.out.println("생성자 호출, url = " + url);
									=> "생성자 호출, url = " + null
							connect();
									=> System.out.println("connect : " + url);
									=> "connect : " + null
							call("초기화 연결 메세지");
				*/
		}
}		

null이 출력되는 이유

객체를 생성하는 단계에는 url이 없고, 객체를 생성한 다음에 외부에서 수정자 주입을 통해 setUrl()이 호출되어야, url이 존재한다.

싱글톤 스프링 빈의 라이프 사이클