Spring bean的创建方式 作用域 生命周期

创建对象的三种方式:

1、采用默认的构造函数创建
2、采用静态工厂方法

  • 1、写一个静态工厂方法类
public class HelloWorldFactory {
	public static HelloWorld getInstance(){
		return new HelloWorld();
 	}
}
  • 2、在spring的配置文件中进行声明
<bean id="helloWorld2" class="com.itheima05.spring.bean.HelloWorldFactory" factory-method="getInstance"></bean>

告诉spring容器利用HelloWorldFactory类中的getInsatance静态方法产生对象
但是具体的对象的创建的过程是由程序员来完成的

3、实例工厂方法

  • 1、写一个实例工厂类
 public class HelloWorldFactory {
     public HelloWorld getInstance(){
        return new HelloWorld();
     }
  }
  • 2、在spring的配置文件中

1)spring容器为HelloWorldFactory2创建对象

 <bean id="helloWorld3" class="com.itheima05.spring.bean.HelloWorldFactory2"></bean>

2)告诉spring容器,利用helloWorld3对象调用getInstance方法

 <bean id="helloWorldFactory" factory-bean="helloWorld3" factory-method="getInstance"></bean>

创建对象的时机
1、在默认的情况下,在spring容器启动的时候创建对象
在spring配置文件中,只要根据以上的三种方式的其中一种配置了,spring容器就会创建对象
好处:
spring容器和web容器整合的时候,当web容器启动的时候就可以初始化spring容器了,如果这个时候spring容器内部有错误,则直接会报错
缺点:
如果该bean中存放着大量的数据,而且数据的初始化发生在创建对象的时候,这个时候,数据会过早的驻留在内存中
2、如果在spring的配置文件中一个bean的配置中有lazy-init=“true”,那么该bean在调用getBean方法时创建对象
缺点:不能过早的发现错误
好处:按照需求加载数据(什么时候要什么时候加载)

作用域scope配置项

作用域限定了Spring Bean的作用范围,在Spring配置文件定义Bean时,通过声明scope配置项,可以灵活定义Bean的作用范围。例如,当你希望每次IOC容器返回的Bean是同一个实例时,可以设置scope为singleton;当你希望每次IOC容器返回的Bean实例是一个新的实例时,可以设置scope为prototype。

scope配置项有5个属性,用于描述不同的作用域。

① singleton

使用该属性定义Bean时,IOC容器仅创建一个Bean实例,IOC容器每次返回的是同一个Bean实例。

② prototype

使用该属性定义Bean时,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。

③ request

该属性仅对HTTP请求产生作用,使用该属性定义Bean时,每次HTTP请求都会创建一个新的Bean,适用于WebApplicationContext环境。

④ session

该属性仅用于HTTP Session,同一个Session共享一个Bean实例。不同Session使用不同的实例。

⑤ global-session

该属性仅用于HTTP Session,同session作用域不同的是,所有的Session共享一个Bean实例。

生命周期

在这里插入图片描述

spring 容器中的bean的完整生命周期一共分为十一步完成。

1.bean对象的实例化

2.封装属性,也就是设置properties中的属性值

3.如果bean实现了BeanNameAware,则执行setBeanName方法,也就是bean中的id值

4.如果实现BeanFactoryAware或者ApplicationContextAware ,需要设置setBeanFactory或者上下文对象setApplicationContext

5.如果存在类实现BeanPostProcessor后处理bean,执行postProcessBeforeInitialization,可以在初始化之前执行一些方法

6.如果bean实现了InitializingBean,则执行afterPropertiesSet,执行属性设置之后的操作

7.调用 < bean init-method=""> 执行指定的初始化方法

8.如果存在类实现BeanPostProcessor则执行postProcessAfterInitialization,执行初始化之后的操作

9.执行自身的业务方法

10.如果bean实现了DisposableBean,则执行spring的的销毁方法

11.调用< bean destory-method="">执行自定义的销毁方法。

第五步和第八步可以结合aop,在初始化执行之前或者执行之后执行一些操作。

以上就是springbean的完整生命周期

代码

public class Man implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
    private String name;

    public Man() {
        System.out.println("第一步:实例化类");
    }

    public void setName(String name) {
        System.out.println("第二步:设置属性");
        this.name = name;
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("第三步:设置bean的名称也就是spring容器中的名称,也就是id值" + name);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("第四步:了解工厂信息ApplicationContext");
    }
    //第五步执行初始化之前执行的方法


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("第六步:属性设置后执行的方法");
    }

    public void setup() {
        System.out.println("第七步:执行自己配置的初始化方法");
    }
    //第八步执行初始化之后执行的方法
    public void run() {
        System.out.println("第九步:执行自身的业务方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("第十步:执行spring的销毁方法");
    }

    public void destory() {
        System.out.println("第十一步:执行自己配置的销毁方法");
    }


}

指定的类实现了BeanPostProcessor
public class MyBeanPostProcess implements BeanPostProcessor {

    //后处理bean,最重要的两步
    @Override
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {
        System.out.println("第五步:初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
        System.out.println("第八步:执行初始化之后的方法");
        return bean;
    }
}

applicationContext.xml中的配置
<bean id="man" class="com.itheima.ioc.springBeanlife.Man" init-method="setup" destroy-method="destory">
    <property name="name" value="张三"/>
</bean>
<bean class="com.itheima.ioc.springBeanlife.MyBeanPostProcess"/>


测试
@Test
public  void beanlifeTest(){
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    Man man=(Man)context.getBean("man");
    man.run();
    context.close();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章