Spring & Springboot/올인원 스프링 프레임워크

Java 파일 분리와 @Import 애너테이션

YJ_ma 2023. 9. 20. 01:54

· 기능 단위로 스프링 설정 파일을 분리하여 개발의 편의성을 높여준다.

· MemberConfig.java 파일을 3개의 파일로 분리하고 스프링 컨테이너 초기화에 이용하는 작업을 수행해본다.

 

분리할 파일 생성하기

· ch06_pjt_01.ems.configuration 패키지에 MemberConfig1, MemberConfig2, MemberConfig3.java 파일을 생성한다.

· 스프링 컨테이너에 빈 객체를 생성하는 역할을 하므로 @Configuration을 명시해준다.

Java 코드 분리하기

MemberConfig1.java

· 학생 정보를 추가, 수정, 검색, 삭제하는 Service 및 DAO 빈 객체를 스프링 컨테이너에 생성하는 코드

·  InitSampleData부터 PrintStudentInformationService까지 복사하여 사용

package ch06_pjt_01.ems.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ch06_pjt_01.ems.member.dao.StudentDao;
import ch06_pjt_01.ems.member.service.PrintStudentInformationService;
import ch06_pjt_01.ems.member.service.StudentAllSelectService;
import ch06_pjt_01.ems.member.service.StudentDeleteService;
import ch06_pjt_01.ems.member.service.StudentModifyService;
import ch06_pjt_01.ems.member.service.StudentRegisterService;
import ch06_pjt_01.ems.member.service.StudentSelectService;
import ch06_pjt_01.ems.utils.InitSampleData;

@Configuration
public class MemberConfig1 {
	@Bean
	public InitSampleData initSampleData() {
		InitSampleData initSampleData = new InitSampleData();

		String[] sNums = {"hbs001", "hbs002", "hbs003", "hbs004", "hbs005"};
		initSampleData.setsNums(sNums);

		String[] sIds = {"rabbit", "hippo", "raccoon", "elephant", "lion"};
		initSampleData.setsIds(sIds);

		String[] sPws = {"p0001", "p0002", "p0003", "p0004", "p0005"};
		initSampleData.setsPws(sPws);

		String[] sNames = {"agatha", "barbara", "chris", "doris", "elva"};
		initSampleData.setsNames(sNames);

		int[] sAges = {19, 22, 20, 27, 19};
		initSampleData.setsAges(sAges);

		char[] sGenders = {'M', 'W', 'W', 'M', 'M'};
		initSampleData.setsGenders(sGenders);

		String[] sMajors = {"English", "Korean", "French", "Philosophy", "History"};
		initSampleData.setsMajors(sMajors);

		return initSampleData;
	}

	@Bean
	public StudentDao studentDao() {
		return new StudentDao();
	}

	@Bean
	public StudentRegisterService studentRegisterService() {
		return new StudentRegisterService(studentDao());
	}

	@Bean
	public StudentModifyService studentModifyService() {
		return new StudentModifyService(studentDao());
	}

	@Bean
	public StudentDeleteService studentDeleteService() {
		return new StudentDeleteService(studentDao());
	}

	@Bean
	public StudentSelectService studentSelectService() {
		return new StudentSelectService(studentDao());
	}

	@Bean
	public StudentAllSelectService studentAllSelectService() {
		return new StudentAllSelectService(studentDao());
	}

	@Bean
	public PrintStudentInformationService printStudentInformationService() {
		return new PrintStudentInformationService(studentAllSelectService());
	}
}

 

MemberConfig2.java

· 데이터베이스와 관련된 빈 객체를 스프링 컨테이너에 생성하는 코드

package ch06_pjt_01.ems.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ch06_pjt_01.ems.member.DBConnectionInfo;

@Configuration
public class MemberConfig2 {
	@Bean
	public DBConnectionInfo dev_DBConnectionInfoDev() {
		DBConnectionInfo dbConnectionInfo = new DBConnectionInfo();
		dbConnectionInfo.setUrl("000.000.000.000");
		dbConnectionInfo.setUserId("admin");
		dbConnectionInfo.setUserPw("0000");

		return dbConnectionInfo;
	}

	@Bean
	public DBConnectionInfo real_DBConnectionInfoDev() {
		DBConnectionInfo dbConnectionInfo = new DBConnectionInfo();
		dbConnectionInfo.setUrl("111.111.111.111");
		dbConnectionInfo.setUserId("master");
		dbConnectionInfo.setUserPw("1111");

		return dbConnectionInfo;
	}
}

 

MemberConfig3.java

· 시스템 정보와 관련한 빈 객체를 생성하는 코드

package ch06_pjt_01.ems.configuration;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import ch06_pjt_01.ems.member.DBConnectionInfo;
import ch06_pjt_01.ems.member.service.EMSInformationService;

@Configuration
public class MemberConfig3 {
	@Bean
	public EMSInformationService eMSInformationService() {
		EMSInformationService emsInformationService = new EMSInformationService();
		emsInformationService.setInfo("Education Management System program was developed in 2022.");
		emsInformationService.setCopyRight("COPYRIGHT(C) 2022 EMS C0., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION.");
		emsInformationService.setVer("The version is 1.0");
		emsInformationService.seteYear(2022);
		emsInformationService.seteMonth(3);
		emsInformationService.seteDay(1);
		emsInformationService.seteYear(2022);
		emsInformationService.seteMonth(4);
		emsInformationService.seteDay(30);

		List<String> developers = new ArrayList<String>();
		developers.add("Cheney.");
		developers.add("Eloy.");
		developers.add("Jasper.");
		developers.add("Dillon.");
		developers.add("Kian.");
		emsInformationService.setDevelopers(developers);

		Map<String, String> administrators = new HashMap<String, String>();
		administrators.put("Cheney", "cheney@springPjt.org");
		administrators.put("Jasper", "jasper@springPjt.org");
		emsInformationService.setAdministrators(administrators);

		Map<String, DBConnectionInfo> dbInfos = new HashMap<String, DBConnectionInfo>();
		dbInfos.put("dev", dev_DBConnectionInfoDev());
		dbInfos.put("real", real_DBConnectionInfoDev());
		emsInformationService.setDbInfos(dbInfos);

		return emsInformationService;
	}
}

 

📣 dbInfos에서 에러 발생!

→ MemberConfig.java 파일을 분리했기 때문에 MemberConfig3.java에서 MemberConfig2에 선언된 dev_DBConnectionInfoDev()와 real_DBConnectionInfoDev() 메서드를 찾을 수 없기 때문이다.

 

💡@Autowired에 의한 의존 객체를 자동 주입 설정

· @Autowired를 이용해서 dev_DBConnectionInfoDev와 real_DBConnectionInfoDev를 초기화하도록 수정

@Autowired
DBConnectionInfo dev_DBConnectionInfoDev;

@Autowired
DBConnectionInfo real_DBConnectionInfoDev;
Map<String, DBConnectionInfo> dbInfos = new HashMap<String, DBConnectionInfo>();
dbInfos.put("dev", dev_DBConnectionInfoDev);
dbInfos.put("real", real_DBConnectionInfoDev);
emsInformationService.setDbInfos(dbInfos);

· BConnectionInfo 타입의 객체를 필요로 하는 메서드를 사용하기 위해서 DBConnectionInfo 타입의 프로퍼티를 선언하고 @Autowired 애너테이션을 이용해서 의존 객체를 자동으로 주입

· @Autowired에 의해서 의존 객체 자동 주입을 설정해주면, 스프링 컨테이너가 MemberConfing2.java의 dev_DBConnectionInfoDev()와 real_DBConnectionInfoDev()에 의해서 생성된 빈 객체가 주입한다.

 

컨테이너 초기화 코드 수정

· MainClassUseConfig.java 파일을 복사해서 MainClassUseConfigs.java를 생성해준다.

· MemberConfig 대신 MemberConfig1, MemberConfig2, MemberConfig3을 사용하도록 수정해준다.

변경 변경
AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MemberConfig.class);
AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MemberConfig1.class, MemberConfig2.class, MemberConfig3.class);

실행 결과

@Import 애너테이션

· XML에서 다른 XML파일을 사용하기 위해 <import /> 태그를 이용했다.

<import resource="classpath:appCtx2.xml" />
<import resource="classpath:appCtx3.xml" />

 

· Java에서는 다른 Java 파일을 임포트하기 위해 @Import 애너테이션을 사용한다. 

1. MemberConfig1.java를 복사하여 MemberConfigImport.java를 생성한다.

2. MemberConfigImport.java를 열어 다음과 같이 @Import 애너테이션을 추가한다.

· @Import 애너테이션에 MemberConfig2.class와 MemberConfig3.class를 배열로 명시했다.

스프링 컨테이너가 초기화할 때 각각의 클래스를 임포트하여 빈 객체를 생성 및 주입

@Configuration
@Import({MemberConfig2.class, MemberConfig3.class})
public class MemberConfigImport {

· 만약 임포트할 클래스가 한 개이면 배열을 삭제하고 다음과 같이 나타낼 수 있다.

@Configuration
@Import(MemberConfig2.class)
public class MemberConfigImport {

 

3. MainClassUseConfigs.java를 복사해서 MainClassUseConfigsImport.java를 생성한다.

· MemberConfigImport.class를 사용하기 위해 다음과 같이 수정한다.

변경 변경
AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MemberConfig1.class, MemberConfig2.class, MemberConfig3.class);
AnnotationConfigApplicationContext ctx = 
    new AnnotationConfigApplicationContext(MemberConfigImport.class);

실행 결과