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=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
${}(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() 소멸자 소멸전...
<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() 소멸자 소멸전...