Spring 복습 생명주기, bean-scope에 따른 차이, <context:property-placeholder>

충찌·2022년 1월 8일
0

Spring-remind

목록 보기
2/4
post-thumbnail

SDLC

software development lifetime cycle(생명주기)

<Student.java>
package sdlc01;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class Student implements InitializingBean, DisposableBean {

	private String name;
	private int age;
	
	public void destroy() throws Exception {
		System.out.println("Student의 destroy()--> 소멸자가 소멸되기전..");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("Student afterPropertiesSet --> 생성자 생성 이후..");
	}

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
	
}


<OtherStudent.java>
package sdlc01;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

public class OtherStudent {
	private String name;
	private int age;
	
	@PostConstruct
	public void initMethod() {
		System.out.println("OtherStudent의 initMethod() 생성자 생성 이후 ");
	}
	@PreDestroy
	public void destroyMethod() {
		System.out.println("OtherStudent의 destroyMenthod() 소멸자가 소멸되기 전..");
	}

	public OtherStudent(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}
	
}


<MainClass.java>
package sdlc01;

import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

	public static void main(String[] args) {
		GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
		System.out.println("1 ctx.load Before");
		ctx.load("classpath:applicationCTX01.xml");
		System.out.println("2 ctx.load After");
		//실제 Bean 생성
		ctx.refresh();
		System.out.println("3 ctx.close Before");
		ctx.close();
		System.out.println("4 ctx.close After");
	}

}


<applicationCTX01.xml>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">


	<context:annotation-config/>
	
	<bean id="student" class="sdlc01.Student">
		<constructor-arg value="김춘추"/>
		<constructor-arg value="30"/>
	</bean>
	
	<bean id="otherStudent" class="sdlc01.OtherStudent">
		<constructor-arg value="유성룡"/>
		<constructor-arg value="50"/>
	</bean>

</beans>


<결과>
1 ctx.load Before
1월 08, 2022 1:46:45 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationCTX01.xml]
2 ctx.load After
1월 08, 2022 1:46:46 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericXmlApplicationContext@6ddf90b0: startup date [Sat Jan 08 13:46:46 KST 2022]; root of context hierarchy
1월 08, 2022 1:46:46 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5c671d7f: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,student,otherStudent,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
Student afterPropertiesSet --> 생성자 생성 이후..
OtherStudent의 initMethod() 생성자 생성 이후 
3 ctx.close Before
1월 08, 2022 1:46:46 오후 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericXmlApplicationContext@6ddf90b0: startup date [Sat Jan 08 13:46:46 KST 2022]; root of context hierarchy
1월 08, 2022 1:46:46 오후 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5c671d7f: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,student,otherStudent,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
OtherStudent의 destroyMenthod() 소멸자가 소멸되기 전..
Student의 destroy()--> 소멸자가 소멸되기전..
4 ctx.close After


Bean-scope

같은 bean을 사용하면 같은 주소값을 사용한다. 값을 변경하면 이전의 값을 변경하게 되며 scope=singleton으로 기본값이기도 함

<Student.java>
package sdlc02;

public class Student {
	private String name;
	private int age;
	
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	
	
}



<MainClass.java>
package sdlc02;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {
	public static void main(String[] args) {
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX02.xml");
		
		Student student1 = ctx.getBean("student", Student.class);
		System.out.println("student1 이름:"+student1.getName());
		System.out.println("student1 나이:"+student1.getAge());
		
		System.out.println("=====================");
		Student student2 = ctx.getBean("student", Student.class);
		student2.setName("강유");
		student2.setAge(55);
		
		System.out.println("student2 이름:"+student2.getName());
		System.out.println("student2 나이:"+student2.getAge());
		
		System.out.println("=====================");
		System.out.println("student1 이름:"+student1.getName());
		System.out.println("student1 나이:"+student1.getAge());
		
		if(student1.equals(student2)) {
			System.out.println("student1 == student2");
		}else {
			System.out.println("student1 != student2");
		}
		ctx.close();
	}
}



<applicationCTX02.xml>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


	<bean id="student" class="sdlc02.Student" scope="singleton">
		<constructor-arg value="흑수돌"/>
		<constructor-arg value="30"/>
	</bean>

</beans>



<결과>
student1 이름:흑수돌
student1 나이:30
=====================
student2 이름:강유
student2 나이:55
=====================
student1 이름:강유
student1 나이:55
student1 == student2

같은 bean을 참조하지만 주소값을 다르게 하고싶은 경우 scope=prototype으로 설정한다.

<applicationCTX02.xml>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">



<bean id="student" class="sdlc02.Student" scope="prototype"> 
		<constructor-arg value="흑수돌"/>
		<constructor-arg value="30"/>
	</bean>

</beans>


<결과>
student1 이름:흑수돌
student1 나이:30
=====================
student2 이름:강유
student2 나이:55
=====================
student1 이름:흑수돌
student1 나이:30
student1 != student2

<context:property-placeholder>(xml)

${}(EL표기법)으로 값을 가져와 사용해준다.

<AdminConnection.java>
package env02;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class AdminConnection implements InitializingBean, DisposableBean {
	private String adminId;
	private String adminPw;
	private String sub_adminId;
	private String sub_adminPw;
	
	public void destroy() throws Exception {
		System.out.println("AdminConnection destroy() 소멸자 소멸전...");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("AdminConnection afterPropertiesSet 생성자 생성이후...");
	}

	public String getAdminId() {
		return adminId;
	}

	public void setAdminId(String adminId) {
		this.adminId = adminId;
	}

	public String getAdminPw() {
		return adminPw;
	}

	public void setAdminPw(String adminPw) {
		this.adminPw = adminPw;
	}

	public String getSub_adminId() {
		return sub_adminId;
	}

	public void setSub_adminId(String sub_adminId) {
		this.sub_adminId = sub_adminId;
	}

	public String getSub_adminPw() {
		return sub_adminPw;
	}

	public void setSub_adminPw(String sub_adminPw) {
		this.sub_adminPw = sub_adminPw;
	}

}



<MainClass.java>
package env02;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {
	public static void main(String[] args) {
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX02.xml");
		
		AdminConnection connection = ctx.getBean("adminConnection", AdminConnection.class);
		System.out.println("adminID: "+connection.getAdminId());
		System.out.println("adminPW: "+connection.getAdminPw());
		System.out.println("sub_adminID: "+connection.getSub_adminId());
		System.out.println("sub_adminPW: "+connection.getSub_adminPw());
        	ctx.close();
	}
}


<applicationCTX02.xml>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<!-- jsp개념으로보면include/import했다고 보면됨 -->
	<context:property-placeholder location="classpath:admin2.properties, classpath:sub_admin2.properties" />
	
	<bean id="adminConnection" class="env02.AdminConnection">
		<property name="adminId">
			<value>${admin.id}</value>
		</property>
		<property name="adminPw">
			<value>${admin.pw}</value>
		</property>
		<property name="sub_adminId">
			<value>${sub_admin.id}</value>
		</property>
		<property name="sub_adminPw">
			<value>${sub_admin.pw}</value>
		</property>
	</bean>
	

</beans>


<admin2.properties>
admin.id=admin
admin.pw=12345



<sub_admin2.properties>
sub_admin.id=sub2
sub_admin.pw=67890


<결과>
AdminConnection afterPropertiesSet 생성자 생성이후...
adminID: admin
adminPW: 12345
sub_adminID: sub2
sub_adminPW: 67890
1월 08, 2022 3:08:17 오후 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.GenericXmlApplicationContext@6ddf90b0: startup date [Sat Jan 08 15:08:17 KST 2022]; root of context hierarchy
1월 08, 2022 3:08:17 오후 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5aebe890: defining beans [org.springframework.context.support.PropertySourcesPlaceholderConfigurer#0,adminConnection]; root of factory hierarchy
AdminConnection destroy() 소멸자 소멸전...

<context:property-placeholder>(Annotation)

<AdminConnection.java>
package env03;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class AdminConnection implements InitializingBean, DisposableBean {
	private String adminId;
	private String adminPw;
	private String sub_adminId;
	private String sub_adminPw;
	
	public void destroy() throws Exception {
		System.out.println("AdminConnection destroy() 소멸자 소멸전...");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("AdminConnection afterPropertiesSet 생성자 생성이후...");
	}

	public String getAdminId() {
		return adminId;
	}

	public void setAdminId(String adminId) {
		this.adminId = adminId;
	}

	public String getAdminPw() {
		return adminPw;
	}

	public void setAdminPw(String adminPw) {
		this.adminPw = adminPw;
	}

	public String getSub_adminId() {
		return sub_adminId;
	}

	public void setSub_adminId(String sub_adminId) {
		this.sub_adminId = sub_adminId;
	}

	public String getSub_adminPw() {
		return sub_adminPw;
	}

	public void setSub_adminPw(String sub_adminPw) {
		this.sub_adminPw = sub_adminPw;
	}

}



<ApplicationConfig.java>
package env03;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

@Configuration
public class ApplicationConfig {
	@Value("${admin.id}")
	private String adminId;
	@Value("${admin.pw}")
	private String adminPw;
	@Value("${sub_admin.id}")
	private String sub_adminId;
	@Value("${sub_admin.pw}")
	private String sub_adminPw;
	
	@Bean
	public static PropertySourcesPlaceholderConfigurer Properties() {
		
	PropertySourcesPlaceholderConfigurer configurer 
				= new PropertySourcesPlaceholderConfigurer(); //환경파일잡을때 쓰이는 객체
	
	System.out.println("2. Properties Run"); //환경작업이 제일 먼저 실행됨 
	//<context:property-placeholder location="classpath:admin2.properties, classpath:sub_admin2.properties" />와 아래와 같음
	Resource[] locations = new Resource[2];
	locations[0] = new ClassPathResource("admin3.properties");
	locations[1] = new ClassPathResource("sub_admin3.properties");
	//System.out.println("PropertySourcesPlaceholderconfigurer1 adminId->"+adminId);
	configurer.setLocations(locations);
	
	return configurer;
	}
	@Bean
	public AdminConnection adminConfig() {
		
		AdminConnection adminConnection = new AdminConnection();
		
		System.out.println("3. adminConfig Run");
		adminConnection.setAdminId(adminId);
		adminConnection.setAdminPw(adminPw);
		adminConnection.setSub_adminId(sub_adminId);
		adminConnection.setSub_adminPw(sub_adminPw);
		
		return adminConnection;
	}
}


<admin3.properties>
admin.id=super
admin.pw=12345


<sub_admin3.properties>
sub_admin.id=sub3
sub_admin.pw=67890


<MainClass.java>
package env03;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainClass {

	public static void main(String[] args) {
		System.out.println("1 Run");
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		System.out.println("4 adminConfig Before Run");
		AdminConnection connection = ctx.getBean("adminConfig", AdminConnection.class);
		System.out.println("5 adminConfig After Run");
		
		System.out.println("connection.getAdminId() adminID: "+connection.getAdminId());
		System.out.println("connection.getAdminPw() adminPW: "+connection.getAdminPw());
		System.out.println("connection.getSub_adminId() sub_adminID: "+connection.getSub_adminId());
		System.out.println("connection.getSub_adminPw() sub_adminPW: "+connection.getSub_adminPw());
		ctx.close();
	}

}



<결과>
1 Run
1월 08, 2022 3:11:50 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6ddf90b0: startup date [Sat Jan 08 15:11:50 KST 2022]; root of context hierarchy
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$2 (file:/Users/sohyun/.m2/repository/org/springframework/spring-core/3.2.3.RELEASE/spring-core-3.2.3.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$2
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2. Properties Run
1월 08, 2022 3:11:51 오후 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [admin3.properties]
1월 08, 2022 3:11:51 오후 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
INFO: Loading properties file from class path resource [sub_admin3.properties]
1월 08, 2022 3:11:51 오후 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@43301423: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,applicationConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,adminConfig,Properties]; root of factory hierarchy
3. adminConfig Run
AdminConnection afterPropertiesSet 생성자 생성이후...
4 adminConfig Before Run
5 adminConfig After Run
connection.getAdminId() adminID: super
connection.getAdminPw() adminPW: 12345
connection.getSub_adminId() sub_adminID: sub3
connection.getSub_adminPw() sub_adminPW: 67890
1월 08, 2022 3:11:51 오후 org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6ddf90b0: startup date [Sat Jan 08 15:11:50 KST 2022]; root of context hierarchy
1월 08, 2022 3:11:51 오후 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@43301423: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,applicationConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,adminConfig,Properties]; root of factory hierarchy
AdminConnection destroy() 소멸자 소멸전...

profile
벨로그? 난 켈로그

0개의 댓글