Spring中IOC创建对象的两种方式和创建时机
最近在学习Spring相关知识,官网文档如下
Spring Core Technologies: https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-injection.
一、创建方式
方式1:通过无参构造方法来创建
package com.zhang.pojo;
public class User {
private String name;
public User(){
System.out.println("This is a no args method!");
}
public void show(){
System.out.println("This is a show method!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="User" class="com.zhang.pojo.User">
<property name="name" value="张三丰"></property>
</bean>
</beans>
MyTest
import com.zhang.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
@Test
public void test1(){
ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
User user = (User)ac.getBean("User");
user.show();
}
}
结果可以发现,在调用show方法之前,User对象已经通过无参构造初始化了!执行结果如下:
方式2:通过有参构造方法来创建
User
package com.zhang.pojo;
public class User {
private String name;
public User(String name){
//System.out.println("This is a no args method!");
this.name = name;
}
public void show(){
System.out.println("This is a show method!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这里是官网详细配置使用方式
beans.xml
<!--第一种:下标赋值-->
<bean id="user" class="com.zhang.pojo.User">
<constructor-arg index="0" value="张三丰"></constructor-arg>
</bean>
<!--第二种:类型赋值。 如果两个参数都是String类型,则没有办法使用。 所以不建议使用第二种 -->
<bean id="user" class="com.zhang.pojo.User">
<constructor-arg type="java.lang.String" value="张三丰"/>
</bean>
<!--第三种:直接通过参数名实现-->
<bean id="user" class="com.zhang.pojo.User">
<constructor-arg name="name" value="张三丰"></constructor-arg>
</bean>
二、什么时候创建对象?
创建时机
1:默认的在Spring容器启动的时候
2:在getBean的时候创建对象(就是拿到配置文件中的标识符的时候创建对象)
在Spring的配置文件bean中有一个属性lazy-init=“default/true/false”
(1)如果lazy-init为”default/false”在启动spring容器时创建对象
(2)如果lazy-init为”true”,在context.getBean时才要创建对象
意义:
(1)在启动spring容器的时候,检查spring容器配置文件的正确性,如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗,但是可以过早发现错误。
(2)getBean时创建对象可以减少内存的消耗,但是不容易发现错误。
注意:
如果一个bean的scope属性为scope=”pototype”时,即使设置了lazy-init=“false”,容器启动时不实例化bean,而是调用getBean方法是实例化的。
三、IOC容器创建对象过程
(1)先通过createBeanFactory创建出一个bean工厂(利用顶级接口BeanFactory下的DefaultListableBeanFactory接口)。
(2)循环创建对象,由于容器中bean默认都是单例,则优先通过getBean,doGetBean从容器中查找。
(3)如果找不到则通过createBean,doCreateBean方法,以反射形式创建对象。一般情况下使用的是无参构造方法(getDeclaredConstructor,newInscance)。
(4)进行对象的属性填充(populateBean)。
(5)进行其它初始化操作(initializingBean)。
参考文章
https://blog.csdn.net/z19950712/article/details/112335806
还没有评论,来说两句吧...