• Spring中的实例生成方式及其生命周期


    三种实例化bean的方式
    1.使用类构造器实例化

    <!-- 使用类构造器实例化,class属性表示要使用的类的全限定名 -->
    <bean id="userDao1" 
        class="com.winner.dao.daoImpl.UserDaoImpl">
    </bean>

    使用反射利用类的无参构造器生成实例。

    2.使用静态工厂方法实例化
    --配置文件:

    <!-- 使用静态工厂方法实例化
        class属性表示工厂类的全限定名
        factory-method属性表示这个工厂类中用于创建实例的静态方法名(必须是static的)
    -->
    <bean id="userDao2" 
        class="com.winner.dao.StaticDaoFactory" 
        factory-method="createUserDaoInstance">
    </bean>

    --工厂类:

    public class StaticDaoFactory {
    // 方法必须声明为static的
        public static Object createUserDaoInstance() {
            System.out.println("StaticDaoFactory.createUserDaoInstance()");
            return new UserDaoImpl();
        }
    }

    3.使用实例化的工厂对象中的方法实例化,首先要构造出工厂实例,然后在生成实例
    --配置文件:

    <!-- 使用实例化工厂对象中的方法实例化
        一、定义工厂bean
        二、定义这个bean是由工厂方法创建的,其中:
            factory-bean属性表示工厂bean的名称(id或name)
            factory-method属性表示这个工厂类中用于创建实例的方法名(不能是static的)
    -->
    <bean id="simpleDaoFactory" 
    class="com.winner.dao.SimpleDaoFactory"></bean>
    <bean id="userDao3" 
        factory-bean="simpleDaoFactory"
        factory-method="createUserDaoInstance">
    </bean>

    --工厂类:

    public class SimpleDaoFactory {
        // 方法不能声明为static的
        public static Object createUserDaoInstance() {
            System.out.println("SimpleDaoFactory.createUserDaoInstance()");
            return new UserDaoImpl();
        }
    }

    我们一般写代码的时候都会分层,显示层,业务层,数据访问层,显示层调用业务层,业务层调用数据访问层。

    数据访问层Dao只需要一个实例,业务层Service只需要一个实例,但是action每一次访问都会生成一个实例。

    ------------

    Bean的作用域
    Spring IoC容器中定义的bean默认只有一个实例(单例的),且默认情况下会在容器启动时初始化bean(饿汉式),但我们可以指定Bean节点的lazy-init="true"来延迟初始化bean(懒汉式),这时候,只有第一次获取bean会才初始化bean。如:
    --创建类:

    public class User {
        public User() {
            System.out.println("初始化了User...");
        }
    }

    --配置文件:

    <!--
        scope属性:用于指定bean的生命周期 singleton:单例的,每次ac.getBean()返回的都是同一个实例.
        prototype:多例的,第次ac.getBean()返回的都是一个新的实例. 默认为singleton。
        lazy-init属性:用于指定在什么时候初始化单例的对象
        false:表示在创建ApplicationContext时就初始化本单例的对象。
        true:表示在第一次调用getBean()获取本对象时才初始化。 默认为default.
    -->
    <bean id="user1" class="com.winner.spring.User"/>

    或是:

    <bean id="user1" class="com.winner.spring.User" scope="singleton"/>

    或是:

    <bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="default"/>

    或是

    <bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="false"/>

    以上几种配置,都是在ApplicationContext容器创建时就生成了User对象。

    <bean id="user1" class="com.winner.spring.User" scope="singleton" lazy-init="true"/>

    当lazy-init取值true时,容器创建不会创建User对象,只有在getBean()时才会创建对象,即延迟加载

    对所有bean都应用延迟初始化:
    方法是在根节点beans中设置属性default-lazy-init="true",如下所示:

    <beans default-lazy-init="true" ...>

    prototype(原型,表示每次获取的都是新对象)

    每次从容器获取bean都是新的对象。

    <bean id="user1" class="com.winner.spring.User"  scope="prototype"/>

    getBean()时生成实例。

     指定Bean的初始化方法和销毁方法
    --创建类:

    public class UserDao {
        private DataSource dataSource;
    
        public DataSource getDataSource() {
            return dataSource;
        }
    
        public void setDataSource(DataSource dataSource) {
            this.dataSource = dataSource;
        }
        /**
         * 初始化方法
         */
        public void init() {
            System.out.println("UserDao.init()  初始化方法");
        }
    
        /**
         * 销毁的方法
         */
        public void destroy() {
            System.out.println("UserDao.destroy()  销毁的方法");
        }
    }

    --配置:

    <!-- 单例的对象,配置了初始化方法与销毁方法 -->
        <bean id="userDao" class="com.winner.spring.UserDao"
            init-method="init" destroy-method="destroy"
    />

    --测试代码:

    // 在ApplicationContext接口中没有定义close()方法,要想调用,就得先转为子类类型才行。
    // 一定要关闭ApplicationContext,给bean配置的销毁方法才会被调用。
    // 在单例时,配置的初始化与销毁方法都会被调用。
    // 在多例时,只有配置的初始化才会被调用。
    @Test
    public void test() throws Exception {
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml", getClass());
        UserDao userDao = (UserDao) ac.getBean("userDao");
        System.out.println(userDao);
            
        ac.close();
    }

    --注意:
    ---如果scope属性为prototype则不受spring缓存的控制,destory方法也将不会执行(scope调为singleton时才会有效)。
    ---要调用ApplicationContext的close()方法才会执行destory方法(在ApplicationContext接口中没有close()方法,需要强转为具体的实现类才可以调用)




  • 相关阅读:
    克服 iOS HTML5 音频的局限
    oracle__删除重复记录__三种方法及总结(转载百度文库)
    Oracle 字符集
    无法通过网页进入em
    Ubuntu 12.04(32位)安装Oracle 11g(32位)全过程以及几乎所有问题的解决办法
    正则表达式30分钟入门教程
    linux下安装jdk
    QTP相关书籍
    假的数论gcd,真的记忆化搜索(Codeforce 1070- A. Find a Number)
    搜索基础_HDU1312_dfs_递归+stack实现+bfs_queue实现
  • 原文地址:https://www.cnblogs.com/winner-0715/p/5322561.html
Copyright © 2020-2023  润新知