Spring何时初始化bean

今天在看《spring源码深度解析》第五章关于bean加载的部分,跟踪源码的过程中产生一个困惑。就是在我的代码中调用getBean以前,在加载xml配置文件的时候对应的bean就已经进行了初始化。
代码如下:
Main.java

public class Main {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("factorybean.xml");
        Car car = (Car) ac.getBean("somecar");
        System.out.println(car);
        Person person = (Person) ac.getBean("person");
        System.out.println(person);
    }
}

Car.java

public   class  Car  {  
    private   int maxSpeed ;  
    private  String brand ;  
    private   double price ;  
    public   int  getMaxSpeed ()   {  
        return   this . maxSpeed ;  
    }  
    public   void  setMaxSpeed ( int  maxSpeed )   {  
        this . maxSpeed  = maxSpeed;  
    }  
    public  String getBrand ()   {  
        return   this . brand ;  
    }  
    public   void  setBrand ( String brand )   {  
        this . brand  = brand;  
    }  
    public   double  getPrice ()   {  
        return   this . price ;  
    }  
    public   void  setPrice ( double  price )   {  
        this . price  = price;  
   }
    @Override
    public String toString() {
        return "Car [maxSpeed=" + maxSpeed + ", brand=" + brand + ", price=" + price + "]";
    } 

}

CarFactoryBean.java

public   class  CarFactoryBean  implements  FactoryBean<Car>  {  
    private  String carInfo ;  
    public  Car getObject ()   throws  Exception  {  
        Car car =  new  Car () ;  
        String []  infos =  carInfo .split ( "," ) ;  
        car.setBrand ( infos [ 0 ]) ;  
        car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;  
        car.setPrice ( Double. valueOf ( infos [ 2 ])) ;  
        return  car;  
    }  
    public  Class<Car> getObjectType ()   {  
        return  Car. class ;  
    }  
    public   boolean  isSingleton ()   {  
        return   false ;  
    }  
    public  String getCarInfo ()   {  
        return   this . carInfo ;  
    }  

    // 接受逗号分割符设置属性信息  
    public   void  setCarInfo ( String carInfo )   {  
        this . carInfo  = carInfo;  
    }
    @Override
    public String toString() {
        return "CarFactoryBean [carInfo=" + carInfo + "]";
    }  

}   

bean配置文件

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

    <bean id="car" class="factorybean.CarFactoryBean" p:carInfo="法拉利,400,2000000" />
    <bean id="person" class="code.Person">
        <property name="name" value="xingoo"/>
        <property name="age" value="12"/>
    </bean>
    <alias name="car" alias="somecar"/><!-- 别名 -->
</beans>

注意包名
针对Main.java,当运行完ApplicationContext ac = new ClassPathXmlApplicationContext(“factorybean.xml”);这句话时,内存中加载了CarFactoryBean和person对应的bean。之后调用getBean(“somecar”),通过CarFactoryBean的getObject()方法获取到了Car的bean。调用getBean(“person”)直接从内从中获取到对应的bean。

通过此例,掌握了Spring加载bean的时机

Spring什么时候实例化bean,首先要分2种情况

第一:如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化 (不管bean是否实现了FactoryBean)

第二:如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:
(1):如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取 (但是如果bean实现了FactoryBean,则ApplicationContext启动的时候先实例化对应的FactoryBean,当第一次使用bean的时候,在通过FactoryBean的getObject方法实例化bean)
(2):如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化
(3):如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值