首先单例和多例的结果不一样,因为ClassPathXmlApplicationContext如果是单例的话是在一开始运行服务器的时候就建好对象,而多例则是getBean时再建;
1.MyBeanPost后置处理器
package com.apesblog.demo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPost implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization");
return null;
}
}
2.User类
package com.apesblog.demo;
public class User {
String name;
public User(String name) {
this.name = name;
}
public User() {
System.out.println("执行无参构造");
}
public void setName(String name) {
this.name = name;
System.out.println("执行set方法");
}
public void initMethod(){
System.out.println("initMethod");
}
public void destroyMethod(){
System.out.println("destroyMethod");
}
}
3.测试类
package com.apesblog.demo.Test1;
import com.apesblog.demo.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
@Test
public void test1(){
System.out.println("启动服务器");
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("bean1.xml");
System.out.println("-----------");
User user = classPathXmlApplicationContext.getBean("user", User.class);
System.out.println(user);
System.out.println("-----------");
User user1 = classPathXmlApplicationContext.getBean("user", User.class);
System.out.println(user1);
classPathXmlApplicationContext.close();
}
}
结果(单例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="user" class="com.apesblog.demo.User" init-method="initMethod" destroy-method="destroyMethod" scope="singleton">
<property name="name" value="apesblog"></property>
</bean>
<bean id="mybeanpost" class="com.apesblog.demo.MyBeanPost"></bean>
</beans>
结果(多例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="user" class="com.apesblog.demo.User" init-method="initMethod" destroy-method="destroyMethod" scope="prototype">
<property name="name" value="apesblog"></property>
</bean>
<bean id="mybeanpost" class="com.apesblog.demo.MyBeanPost"></bean>
</beans>
总结:
ClassPathXmlApplicationContext类会在启动服务器的时候创建好Bean,
BeanFactory会在getBean时才创建Bean,但是ClassPathXmlApplicationContext提前创建可能运行时性能上快一点。
单例模式下:
Bean是在启动服务器就创建好的,每次执行getBean返回同一个引用就行,最后再执行destroyMethod方法。
多例模式下:
Bean是在每次执行getBean才创建,但是destroyMethod方法为啥不执行,目前不清楚。
补充:
- 多实例的时候bean不会随着IOC容器的构建而创建,而是在使用的时候创建的getBean()
- 多实例的时候,当容器进行关闭的时候,bean实例不会调用destroy方法,说明容器不控制多实例的销毁
- 多实例的情况下,返回的bean的对象是不一样的
评论区