精华内容
下载资源
问答
  • Java spring bean 生命周期

    千次阅读 2013-03-03 23:46:43
    Spring bean生命周期 在传统的Java应用,Bean的生命周期非常简单。 Java的关键词new用来实例化Bean(或许他是非序列化的)。这样就够用了。 相反,Bean的生命周期在Spring容器更加细致。 理解Spring Bean的...
    Spring bean生命周期
    在传统的Java应用中,Bean的生命周期非常简单。 
    Java的关键词new用来实例化Bean(或许他是非序列化的)。这样就够用了。 
    相反,Bean的生命周期在Spring容器中更加细致。 
    理解Spring Bean的生命周期非常重要,因为你或许要利用Spring提供的机会来订制Bean的创建过程。 
    
    1.容器寻找Bean的定义信息并且将其实例化。 
    
    2.受用依赖注入,Spring按照Bean定义信息配置Bean的所有属性。 
    
    3.如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。 
    
    4.如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。 
    
    5.如果BeanPostProcessor和Bean关联,那么它们的postProcessBeforeInitialzation()方法将被调用。 
    
    6.如果Bean指定了init-method方法,它将被调用。 
    
    7.最后,如果有BeanPsotProcessor和Bean关联,那么它们的postProcessAfterInitialization()方法将被调用。 
    到这个时候,Bean已经可以被应用系统使用了,并且将被保留在Bean Factory中知道它不再需要。 
    
    有两种方法可以把它从Bean Factory中删除掉。 
    
    1.如果Bean实现了DisposableBean接口,destory()方法被调用。 
    
    2.如果指定了订制的销毁方法,就调用这个方法。 
    
    Bean在Spring应用上下文的生命周期与在Bean工厂中的生命周期只有一点不同, 
    唯一不同的是,如果Bean实现了ApplicationContextAwre接口,setApplicationContext()方法被调用。 
    
    只有singleton行为的bean接受容器管理生命周期。 
    non-singleton行为的bean,Spring容器仅仅是new的替代,容器只负责创建。 
    
    
    对于singleton bean,Spring容器知道bean何时实例化结束,何时销毁, 
    Spring可以管理实例化结束之后,和销毁之前的行为,管理bean的生命周期行为主要未如下两个时机: 
    Bean全部依赖注入之后 
    Bean即将销毁之前 
    
    1)依赖关系注入后的行为实现: 
    有两种方法:A.编写init方法  B.实现InitializingBean接口 
    afterPropertiesSet和init同时出现,前者先于后者执行,使用init方法,需要对配置文件加入init-method属性 
    
    2)bean销毁之前的行为 
    有两种方法:A.编写close方法  B.实现DisposableBean接口 
    destroy和close同时出现,前者先于后者执行,使用close方法,需要对配置文件加入destroy-method属性 

    展开全文
  • Spring中Bean生命周期的意义:可以利用Bean在其存活期间的特定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,常会在Bean的postinitiation(初始化后)和predestruction(销毁前)执行一些相关操作。 ...

    Spring中Bean的生命周期的意义:可以利用Bean在其存活期间的特定时刻完成一些相关操作。这种时刻可能有很多,但一般情况下,常会在Bean的postinitiation(初始化后)和predestruction(销毁前)执行一些相关操作。

    Bean的生命周期管理: Spring容器可以管理Bean部分作用域的生命周期。

    • singleton作用域
      Spring容器可以管理singleton作用域的Bean的生命周期,在此作用域下,Spring能够精确的知道该Bean何时被创建,何时初始化完成,以及何时被销毁。
    • prototype作用域
      prototype作用域的Bean,Spring只负责创建,当容器创建了Bean实例后,Bean的实例就交给客户端代码来管理,Spring容器将不再跟踪其生命周期。

    生命周期图:
    在这里插入图片描述
    生命周期的接口以及方法,

    • BeanNameAware 接口
      implements继承到接口,import导入相对应的包,然后再重写setBeanName方法,该方法可以获得本身的id属性,代码如下所示:
     @Override
    public void setBeanName(String arg0) { //获得本身bean的id属性。
    	System.out.println("Bean对象名:"+arg0);
    }
    
    • BeanFactoryAware接口
      同上继承接口,再导入包,重写方法。该接口可以找到相应的beanfactory的实例引用

    • ApplicationContextAware接口

    展开全文
  • java bean生命周期

    万次阅读 2018-12-13 09:47:49
    Spring 中bean生命周期短暂吗? 在spring,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一...

    文章转载来自博客园:https://www.cnblogs.com/kenshinobiy/p/4652008.html

    Spring 中bean 的生命周期短暂吗?

    在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一实例,对单线程的程序说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程同时存取共享资源所引发的数据不同步问题。

    然而在spring中可以设定每次从BeanFactory或ApplicationContext指定别名并取得Bean时都产生一个新的实例:例如:

    在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的Bean时都会产生一个新的实例

    一个Bean从创建到销毁,如果是用BeanFactory来生成,管理Bean的话,会经历几个执行阶段(如图1.1):

     

    注意:红色字体为面试涉及部分

    1:Bean的建立:

    容器寻找Bean的定义信息并将其实例化。

    2:属性注入:

    使用依赖注入,Spring按照Bean定义信息配置Bean所有属性

    3:BeanNameAware的setBeanName()

    如果Bean类有实现org.springframework.beans.BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。

    4:BeanFactoryAware的setBeanFactory():

    如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身。

    5:BeanPostProcessors的ProcessBeforeInitialization()

    如果有org.springframework.beans.factory.config.BeanPostProcessors和Bean关联,那么其postProcessBeforeInitialization()方法将被将被调用。

    6:initializingBean的afterPropertiesSet():

    如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法

    7:Bean定义文件中定义init-method:

    可以在Bean定义文件中使用"init-method"属性设定方法名称例如:

    如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法

    8:BeanPostProcessors的ProcessaAfterInitialization()

    <!-- 配置我们自己的后置处理器(有点类似我们的filter) -->

    如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法

    此时,Bean已经可以被应用系统使用,并且将保留在BeanFactory中知道它不在被使用。有两种方法可以将其从BeanFactory中删除掉(如图1.2):

     

     

    1:DisposableBean的destroy()

    在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法

    2:Bean定义文件中定义destroy-method

    在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称,例如:

     

    如果有以上设定的话,则进行至这个阶段时,就会执行destroy()方法,如果是使用ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。


      找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下。

        在说明前可以思考一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;

        Spring上下文中的Bean也类似,如下

        1、实例化一个Bean--也就是我们常说的new;

        2、按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;

        3、如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值

        4、如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);

        5、如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);

        6、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;

        7、如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。

        8、如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;

        注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。

        9、当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;

        10、最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

     

    以上10步骤可以作为面试或者笔试的模板,另外我们这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了。

     


     

     

      这Spring框架中,一旦把一个bean纳入到Spring IoC容器之中,这个bean的生命周期就会交由容器进行管理,一般担当管理者角色的是BeanFactory或ApplicationContext。认识一下Bean的生命周期活动,对更好的利用它有很大的帮助。

        下面以BeanFactory为例,说明一个Bean的生命周期活动:

    • Bean的建立

          由BeanFactory读取Bean定义文件,并生成各个实例。

    • Setter注入

          执行Bean的属性依赖注入。

    • BeanNameAware的setBeanName()

          如果Bean类实现了org.springframework.beans.factory.BeanNameAware接口,则执行其setBeanName()方法。

    • BeanFactoryAware的setBeanFactory()

          如果Bean类实现了org.springframework.beans.factory.BeanFactoryAware接口,则执行其setBeanFactory()方法。

    • BeanPostProcessors的processBeforeInitialization()

          容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processBeforeInitialization()方法。

    • InitializingBean的afterPropertiesSet()

          如果Bean类实现了org.springframework.beans.factory.InitializingBean接口,则执行其afterPropertiesSet()方法。

    • Bean定义文件中定义init-method

          在Bean定义文件中使用“init-method”属性设定方法名称,如下:

    <bean id="demoBean" class="com.yangsq.bean.DemoBean" init-method="initMethod">
      .......
     </bean>

          这时会执行initMethod()方法,注意,这个方法是不带参数的。

    • BeanPostProcessors的processAfterInitialization()

          容器中如果有实现org.springframework.beans.factory.BeanPostProcessors接口的实例,则任何Bean在初始化之前都会执行这个实例的processAfterInitialization()方法。

    • DisposableBean的destroy()

          在容器关闭时,如果Bean类实现了org.springframework.beans.factory.DisposableBean接口,则执行它的destroy()方法。

    • Bean定义文件中定义destroy-method

          在容器关闭时,可以在Bean定义文件中使用“destory-method”定义的方法

    <bean id="demoBean" class="com.yangsq.bean.DemoBean" destory-method="destroyMethod">
      .......
    </bean>

           这时会执行destroyMethod()方法,注意,这个方法是不带参数的。

       以上就是BeanFactory维护的一个Bean的生命周期。下面这个图可能更直观一些:

       如果使用ApplicationContext来维护一个Bean的生命周期,则基本上与上边的流程相同,只不过在执行BeanNameAware的setBeanName()后,若有Bean类实现了org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,然后再进行BeanPostProcessors的processBeforeInitialization()

       实际上,ApplicationContext除了向BeanFactory那样维护容器外,还提供了更加丰富的框架功能,如Bean的消息,事件处理机制等。

    展开全文
  • IOC容器bean的生命周期,iocbean生命周期 一、Bean的生命周期 Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。 Spring IOC容器对Bean的生命周期进行管理的过程...

    原文地址:http://www.bkjia.com/Javabc/1149957.html

    IOC容器中bean的生命周期,iocbean生命周期


    一、Bean的生命周期

    Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。

    Spring IOC容器对Bean的生命周期进行管理的过程如下:

    (1).通过构造器或工厂方法创建Bean实例。

    (2).为Bean的属性设置值和对其它Bean的引用。

    (3).调用Bean的初始化方法。

    (4).Bean的使用。

    当容器关闭时,调用Bean的销毁方法。

    在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法。

    示例:User实体类:

    package com.atguigu.spring.helloworld;
    
    import java.util.List;
    
    public class User {
    
    	private String userName;
    	private List<Car> cars;
    	
    	private String wifeName;
    	
    	public String getWifeName() {
    		return wifeName;
    	}
    
    	public void setWifeName(String wifeName) {
    		System.out.println("设置wifeName属性。。。"+wifeName);
    		this.wifeName = wifeName;
    	}
    
    	public String getUserName() {
    		return userName;
    	}
    
    	public void setUserName(String userName) {
    		System.out.println("设置userName属性。。。"+userName);
    		this.userName = userName;
    	}
    
    	public List<Car> getCars() {
    		return cars;
    	}
    
    	public void setCars(List<Car> cars) {
    		this.cars = cars;
    	}
    	// 构造方法
    	public User() {
    		System.out.println("正在使用构造方法 Construtor...");
    	}
    
    	@Override
    	public String toString() {
    		return "User [userName=" + userName + ", cars=" + cars + "]";
    	}
    	// 初始化方法
    	public void init(){
    		System.out.println("init method...");
    	}
    	// 销毁方法
    	public void destroy(){
    		System.out.println("destroy method...");
    	}
    }

      配置文件beans-auto.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-4.0.xsd">
    
    	<!-- 自动装配: 只声明 bean, 而把 bean 之间的关系交给 IOC 容器来完成 -->
    	<!--  
    		byType: 根据类型进行自动装配. 但要求 IOC 容器中只有一个类型对应的 bean, 若有多个则无法完成自动装配.
    		byName: 若属性名和某一个 bean 的 id 名一致, 即可完成自动装配. 若没有 id 一致的, 则无法完成自动装配
    	-->
    	<!-- 在使用 XML 配置时, 自动转配用的不多. 但在基于 注解 的配置时, 自动装配使用的较多.  -->
    	<bean id="dao" class="com.atguigu.spring.ref.Dao">
    		<property name="dataSource" value="C3P0"></property>				
    	</bean>
    	
    	<!-- 默认情况下 bean 是单例的! -->
    	<!-- 但有的时候, bean 就不能使单例的. 例如: Struts2 的 Action 就不是单例的! 可以通过 scope 属性来指定 bean 的作用域 -->
    	<!--  
    		prototype: 原型的. 每次调用 getBean 方法都会返回一个新的 bean. 且在第一次调用 getBean 方法时才创建实例
    		singleton: 单例的. 每次调用 getBean 方法都会返回同一个 bean. 且在 IOC 容器初始化时即创建 bean 的实例. 默认值 
    	-->
    	<bean id="dao2" class="com.atguigu.spring.ref.Dao" scope="prototype"></bean>
    	
    	<bean id="service" class="com.atguigu.spring.ref.Service" autowire="byName"></bean>
    	
    	<bean id="action" class="com.atguigu.spring.ref.Action" autowire="byType"></bean>
    	
    	<!-- 导入外部的资源文件 -->
    	<context:property-placeholder location="classpath:db.properties"/>
    	
    	<!-- 配置数据源 -->
    	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    		<property name="user" value="${jdbc.user}"></property>
    		<property name="password" value="${jdbc.password}"></property>
    		<property name="driverClass" value="${jdbc.driverClass}"></property>
    		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    		
    		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
    		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    	</bean>
    	
    	<!-- 测试 SpEL: 可以为属性进行动态的赋值(了解) -->
    	<bean id="girl" class="com.atguigu.spring.helloworld.User">
    		<property name="userName" value="周迅"></property>
    	</bean>
    	
    	<bean id="boy" class="com.atguigu.spring.helloworld.User" init-method="init" destroy-method="destroy">
    		<property name="userName" value="高胜远"></property>
    		<property name="wifeName" value="#{girl.userName}"></property>
    	</bean>
    	
    	<!-- 配置 bean 后置处理器: 不需要配置 id 属性, IOC 容器会识别到他是一个 bean 后置处理器, 并调用其方法 -->
    	<bean class="com.atguigu.spring.ref.MyBeanPostProcessor"></bean>
    	
    	<!-- 通过工厂方法的方式来配置 bean -->
    	<!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->
    	<!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->
    	<bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
    		<!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
    		<constructor-arg value="2"></constructor-arg>
    	</bean>
    	
    	<!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->
    	<!-- ①. 创建工厂对应的 bean -->
    	<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
    		<constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>
    	</bean>
    	
    	<!-- ②. 有实例工厂方法来创建 bean 实例 -->
    	<!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->
    	<bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">
    		<!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->
    		<constructor-arg value="1990-12-12 12:12:12"></constructor-arg>
    	</bean>
    	
    	<!-- 配置通过 FactroyBean 的方式来创建 bean 的实例(了解) -->
    	<bean id="user" class="com.atguigu.spring.ref.UserBean"></bean>
    	
    </beans>
    

      测试Main函数:

    package com.atguigu.spring.ref;
    
    import java.sql.SQLException;
    import java.text.DateFormat;
    import java.util.Date;
    
    import javax.sql.DataSource;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.atguigu.spring.helloworld.User;
    
    public class Main {
    	
    	public static void main(String[] args) throws SQLException {
    		
    		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-auto.xml");
    		
    		//测试 spEL
    		User boy = (User) ctx.getBean("boy");
    		System.out.println(boy);
    		
    		ctx.close();
    	}
    	
    }

    测试结果:

    说明:首先通过构造函数来创建bean的实例,然后通过setter方法设置属性,在使用bean实例之前,执行了init初始化方法,使用之后又执行了destroy方法。

    二、创建Bean的后置处理器

    Bean后置处理允许在调用初始化方法前后对Bean进行额外的处理,Bean后置处理器对IOC容器的所有Bean实例逐一处理,而非单一实例。其典型应用是:检查Bean属性的正确性或根据特定的标准更改Bean的属性。

    对Bean后置处理器而言,需要实现接口BeanPostProcessor,在初始化方法被调用前后,Spring将把每个Bean实例分别传递给上述接口的以下两个方法:

     添加Bean后置处理器后,Spring IOC容器对Bean的生命周期管理的过程为:  

    示例演示Bean的后置处理器:

    先定义MyBeanPostProcessor类并实现BeanPostProcessor接口:

    package com.atguigu.spring.ref;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    
    import com.atguigu.spring.helloworld.User;
    
    public class MyBeanPostProcessor implements BeanPostProcessor {
    
    	//该方法在 init 方法之后被调用
    	@Override
    	public Object postProcessAfterInitialization(Object arg0, String arg1)
    			throws BeansException {
    		if(arg1.equals("boy")){
    			System.out.println("postProcessAfterInitialization..." + arg0 + "," + arg1);
    			User user = (User) arg0;
    			user.setUserName("李大齐");
    		}
    		return arg0;
    	}
    
    	//该方法在 init 方法之前被调用
    	//可以工作返回的对象来决定最终返回给 getBean 方法的对象是哪一个, 属性值是什么
    	/**
    	 * @param arg0: 实际要返回的对象
    	 * @param arg1: bean 的 id 值
    	 */
    	@Override
    	public Object postProcessBeforeInitialization(Object arg0, String arg1)
    			throws BeansException {
    		if(arg1.equals("boy"))
    			System.out.println("postProcessBeforeInitialization..." + arg0 + "," + arg1);
    		return arg0;
    	}
    
    }
    

      bean-auto.xml文件中配置Bean的后置处理器bean,<bean class="com.atguigu.spring.ref.MyBeanPostProcessor"></bean>在上面的配置文件中已标注,不再赘述。

    main函数测试类在与上文相同,测试结果如下:

    说明:和上面的测试结果对比可以看出,多了一个在bean初始化方法之前将 Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法和在执行bean初始化方法之后将 Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization方法

    三、通过工厂方法创建Bean

    3.1、静态工厂方法创建Bean

    创建Car实体类:

    package com.atguigu.spring.ref;
    
    public class Car {
    
    	private String company;
    	private String brand;
    
    	private int maxSpeed;
    	private float price;
    
    	public Car() {
    	}
    
    	public Car(String company,float price) {
    		super();
    		this.company = company;
    		this.price = price;
    	}
    
    	@Override
    	public String toString() {
    		return "Car [company=" + company + ", brand=" + brand + ", maxSpeed="
    				+ maxSpeed + ", price=" + price + "]";
    	}
    }
    

      创建静态工厂方法:

    package com.atguigu.spring.ref;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class StaticCarFactory {
    	private static Map<String, Car> cars = new HashMap<String, Car>();
    	
    	static {
    		cars.put("Audi", new Car("Audi", 300000));
    		cars.put("Ford", new Car("Ford", 500000));
    	}
    
    	// 静态工厂方法
    	public static Car getCar(String name) {
    		return cars.get(name);
    	}
    }
    

      bean-auto.xml配置静态工厂方法bean:

    <?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-4.0.xsd">
    	
    	<!-- 通过工厂方法的方式来配置 bean -->
    	<!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->
    	<!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->
    	<bean id="car" class="com.atguigu.spring.ref.StaticCarFactory" factory-method="getCar">
    		<!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
    		<constructor-arg value="Audi"></constructor-arg>
    	</bean>
    
    
    	<bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
    		<!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
    		<constructor-arg value="2"></constructor-arg>
    	</bean>
    	
    	<!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->
    	<!-- ①. 创建工厂对应的 bean -->
    	<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
    		<constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>
    	</bean>
    	
    	<!-- ②. 有实例工厂方法来创建 bean 实例 -->
    	<!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->
    	<bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">
    		<!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->
    		<constructor-arg value="1990-12-12 12:12:12"></constructor-arg>
    	</bean>
    	
    	<!-- 配置通过 FactroyBean 的方式来创建 bean 的实例(了解) -->
    	<bean id="user" class="com.atguigu.spring.ref.UserBean"></bean>
    	
    </beans>
    

      测试函数:

    package com.atguigu.spring.ref;
    
    import java.sql.SQLException;
    import java.text.DateFormat;
    import java.util.Date;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class Main {
    	
    	public static void main(String[] args) throws SQLException {
    		
    		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-auto.xml");
    		Car car = (Car) ctx.getBean("car");
    		System.out.println(car+"**********");
    		
    		ctx.close();
    	}
    	
    }
    

      执行结果:

    3.2、实例工厂方法创建Bean

    实例工厂方法: 将对象的创建过程封装到另外一个对象实例的方法里. 当客户端需要请求对象时, 只需要简单的调用该实例方法而不需要关心对象的创建细节。

    要声明通过实例工厂方法创建的 Bean
    (1).在 bean 的 factory-bean 属性里指定拥有该工厂方法的 Bean
    (2).在 factory-method 属性里指定该工厂方法的名称
    (3).使用 construtor-arg 元素为工厂方法传递方法参数

    也可以通过实现FactoryBean接口来创建Bean的实例:

    创建UserBean并实现FactoryBean接口:

    package com.atguigu.spring.ref;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.FactoryBean;
    
    import com.atguigu.spring.helloworld.Car;
    import com.atguigu.spring.helloworld.User;
    
    public class UserBean implements FactoryBean<User>{
    
    	/**
    	 * 返回的 bean 的实例
    	 */
    	@Override
    	public User getObject() throws Exception {
    		User user = new User();
    		user.setUserName("abc");
    		user.setWifeName("ABC");
    		
    		List<Car> cars = new ArrayList<>();
    		cars.add(new Car("ShangHai", "BuiKe", 180, 300000));
    		cars.add(new Car("ShangHai", "CRUZE", 130, 150000));
    		
    		user.setCars(cars);
    		return user;
    	}
    
    	/**
    	 * 返回的 bean 的类型
    	 */
    	@Override
    	public Class<?> getObjectType() {
    		return User.class;
    	}
    
    	/**
    	 * 返回的 bean 是否为单例的
    	 */
    	@Override
    	public boolean isSingleton() {
    		return true;
    	}
    
    }
    

      bean-auto.xml文件中配置bean:

    <?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-4.0.xsd">
    	<!-- 通过工厂方法的方式来配置 bean -->
    	<!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->
    	<!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->
    	<bean id="car" class="com.atguigu.spring.ref.StaticCarFactory" factory-method="getCar">
    		<!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
    		<constructor-arg value="Audi"></constructor-arg>
    	</bean>
    	<bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
    		<!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
    		<constructor-arg value="2"></constructor-arg>
    	</bean>
    	
    	<!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->
    	<!-- ①. 创建工厂对应的 bean -->
    	<bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
    		<constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>
    	</bean>
    	
    	<!-- ②. 有实例工厂方法来创建 bean 实例 -->
    	<!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->
    	<bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">
    		<!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->
    		<constructor-arg value="1990-12-12 12:12:12"></constructor-arg>
    	</bean>
    	
    	<!-- 配置通过 FactroyBean 的方式来创建 bean 的实例(了解) -->
    	<bean id="user" class="com.atguigu.spring.ref.UserBean"></bean>
    	
    </beans> 

    四、Bean的作用域

    scope用来声明容器中的对象所应该处的限定场景或者说该对象的存活时间。

    1、singleton

    标记为拥有singleton的对象定义,在Spring的IOC容器中只存在一个实例,所有对该对象的引用将共享这个实例。该实例从容器启动,并因为第一次请求而初始化之后,将一直存活到容器退出。

    2、prototype

    拥有prototype的bean定义,容器在接到该类型对象的请求的时候,会每次都重新生成一个新的对象实例给请求方,虽然这种类型的对象的实例化以及属性设置等工作都是由容器负责的,但是只要准备完毕,并且对象实例返回给请求方之后,容器就不在拥有当前返回对象的引用。

    3、request、session和global session

    这三类只适用于Web应用程序,通常是与XmlWebApplicationContext共同使用。request:XmlWebApplicationContext会为每个http请求创建一个全新的request-processor对象供当前请求使用,当请求结束后,该对象实例的生命周期即告结束。request可以看做是prototype的一种特例,除了应用场景更加具体。

    session:Spring容器会为每个独立的session创建属于他们自己的全新的对象实例,与request相比,除了拥有更长的存活时间,其他没什么差别。

    global session:只在基于portlet的web应用程序中才有意义


    展开全文
  • Java EE CDI bean生命周期介绍

    千次阅读 热门讨论 2015-03-31 11:27:24
    这篇博客主要介绍CDI提供的不同bean生命周期及在项目如何使用它们。 介绍 当一个bean被CDI初始化时,这个bean通常会有自己的作用域。而赋予它的作用域通常就会决定了这个bean的整个生命周期。CDI提供的bean的...
  • Bean生命周期

    千次阅读 2016-02-20 11:43:04
    Bean生命周期 基本概述  生命周期一直是很重要的内容,从以前Java对象、Servlet的生命周期可以看出,只有理解了其生命周期,才能知道应该在哪阶段完成哪阶段的事。Bean被载入到容器的时候,它的生命周期就...
  • Spring中bean的作用域与生命周期

    万次阅读 多人点赞 2017-06-17 22:29:18
    在Spring,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象,除此之外,bean就与应用程序的其他对象没有什么区别了。而bean的定义...
  • Spring容器中bean生命周期

    千次阅读 多人点赞 2019-11-01 23:43:11
    在传统的Java应用bean生命周期很简单。使用Java关键字new进行bean实例化,然后该bean就可以使用了。一旦该bean不再被使用,则由Java自动进行垃圾回收。相比之下,Spring容器bean生命周期就显得相对复杂...
  • SpringBean生命周期详解

    千次阅读 2020-10-28 17:51:28
    SpringBean生命周期详解 一、简述: Spring是我们每天都在使用的框架,Bean是被Spring管理的Java对象,是Spring框架最重要的部分之一,那么让我们一起了解一下SpringBean的生命周期是怎样的吧 二、流程图 我们先从...
  • 希望你也加入到人工智能的队伍来!请点击http://www.captainbed.net ① Spring IoC容器找到关于Bean的定义并实例化该Bean。 ② Spring IoC容器对Bean进行依赖注入。 ③ 如果Bean实现了BeanNameAware接口,则将该...
  • Spring Bean生命周期详解

    万次阅读 多人点赞 2016-08-12 17:40:08
    Spring Bean生命周期详解
  • JAVA面试题:Spring中bean生命周期

    万次阅读 多人点赞 2018-05-09 18:53:44
    Spring 中bean生命周期短暂吗?在spring,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使用Singleton模式产生单一...
  • spring管理bean生命周期

    2016-06-03 13:58:29
    Spring IOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务。 Spring IOC容器对Bean的生命周期进行管理的过程: 1.通过构造器或工厂方法创建Bean实例 2.为Bean的属性设置值和对...
  • 主要介绍了Java的Spring框架中bean的定义以及生命周期,bean的实例化是Java web开发的重要基础,需要的朋友可以参考下
  • 创建Bean的入口:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean。 实例化 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#...
  • Spring中bean生命周期(最详细)

    万次阅读 多人点赞 2020-02-24 14:09:35
    Spring Bean生命周期指的是从一个普通的Java类变成Bean的过程,深知Spring源码的人都知道这个给面试官将的话大可将30分钟以上,如果你不知道源码,那么Aware接口和调用init方法这样的,所以这个问题即考察对Spring...
  • Spring Bean生命周期

    2019-07-09 20:19:57
    Spring Bean生命周期生命周期 生命周期 生命周期过程总概述: 通过构造方法或工厂方法创建bean对象——>为bean属性赋值——>调用 bean 的初始化方法,即init-method指定方法——>bean实例化完毕,可以使用...
  • Spring 中Bean生命周期

    千次阅读 多人点赞 2019-05-11 10:09:12
    文章目录Spring 中Bean生命周期前言一、Bean 的完整生命周期二、Bean生命周期验证 前言 ​ 这其实是一道面试题,是我在面试百度的时候被问到的,当时没有答出来(因为自己真的很菜),后来在网上寻找答案,看到...
  • springBean生命周期

    千次阅读 多人点赞 2020-12-18 14:46:36
    一、springBean生命周期 1、 启动spring容器,也就是创建beanFactory(bean工厂), 一般用的是beanFactory的子类applicationcontext, applicationcontext比一般的beanFactory要多很多功能,比如aop、事件等。 通过...
  • spring bean生命周期

    2014-06-03 20:50:21
    Spring IOC容器可以管理Bean的生命周期,Spring允许在Bean生命周期的特定点执行定制的任务Spring IOC容器对Bean的生命周期进行管理的过程: 通过构造器或工厂方法创建Bean实例为Bean的属性设置值和对其他Bean的...
  • Spring中Bean生命周期

    2021-03-02 15:39:32
    在传统的Java应用bean生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。 相比之下,Spring管理Bean生命周期就复杂多了,...
  •  Spring IOC容器可以管理Bean的生命周期,允许在Bean生命周期的特定点执行定制的任务。  Spring IOC容器对Bean的生命周期进行管理的过程如下: 通过构造器或工厂方法创建Bean实例 为Bean的属性设置值和对其它...
  • Spring中bean生命周期

    千次阅读 2019-03-12 16:13:30
    bean生命周期 一、生命周期流程图: Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。 若容器注册了以上各种接口,程序那么将会按照以上的流程进行...
  • Spring bean生命周期

    2013-12-11 17:07:52
     在传统的Java应用Bean生命周期非常简单。 Java的关键词new用来实例化Bean(或许他是非序列化的)。这样就够用了。 相反,Bean生命周期在Spring容器更加细致。 理解Spring Bean生命周期非常重要...
  • 图解Spring中bean生命周期

    千次阅读 2019-08-04 14:07:53
    Bean生命周期 正确理解Spring bean生命周期非常重要,因为你或许要利用Spring提供的扩展点来完成特定需求。如下图展示了bean 装载到Spring应用上下文中的一个典型的生命周期过程。 接下来我们对该图的内容...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,233
精华内容 32,893
关键字:

java中bean的生命周期

java 订阅