• Spring第四篇:bean实例的创建方式


      Spring容器中bean的创建方式,有如下四种常见方式:

    1. 通过反射调用构造方法创建bean对象

    2. 通过静态工厂方法创建bean对象

    3. 通过实例工厂方法创建bean对象

    4. 通过FactoryBean创建bean对象

      一、通过反射调用构造:调用类的构造器方法创建对应bean的实例,是使用最多的方式。这种方式只需要在bean.xml元素中指定class属性,Spring会自动调用构造方法来创建对象。Spring会根据xml中的配置元数据信息来确定使用哪个构造方法创建bean实例。

      xml文件配置

      <!--有参构造方法-->
        <bean id="user1" class="com.java.spring01.demo2.UserModel">
            <constructor-arg name="name" value="通过构造方法创建bean对象"/>
            <constructor-arg name="age" value="30"/>
            <constructor-arg name="sex" value="男"/>
        </bean>
        <!--无参构造方法-->
        <bean id="user2" class="com.java.spring01.demo2.UserModel"/>

      test方法:

    public class BeanCreateTest {
        private ClassPathXmlApplicationContext context;
    
        @Before
        public void befor(){
            String beanXml = "classpath:spring01/demo3/bean.xml";
            context = new ClassPathXmlApplicationContext(beanXml);
        }
    
        /**
         * 使用构造方法获取实例
         */
        @Test
        public void test1(){
            String[] definitionNames = context.getBeanDefinitionNames();
            for (String beanName : definitionNames){
                Object bean = context.getBean(beanName);
                if(bean instanceof UserModel){
                    System.out.println(bean.toString());
                }
            }
        }
    
    }

      运行结果,会根据bean.xml文件中的配置顺序,调用相应的构造方法进行对象实例化。

    调用you参构造方法初始化实例对象
    调用无参构造方法初始化实例对象
    UserModel{name='通过构造方法创建bean对象', age=30, sex='男'}
    UserModel{name='null', age=0, sex='null'}

      二、通过静态工厂方法创建bean对象:可以通过工厂类的静态方法来创建bean对象,供Spring调用。

      xml文件中增加配置,class直接引用静态工厂(非静态类包含静态方法)

    <!--无参静态工厂方法获取bean对象-->
        <bean id="user3" class="com.java.spring01.demo3.UserStaticFactory" factory-method="getUser1"/>
    
        <!--有参静态工厂方法获取bean对象-->
        <bean id="user5" class="com.java.spring01.demo3.UserStaticFactory" factory-method="getUser2">
            <constructor-arg name="name" value="通过静态工厂方法创建bean对象"/>
            <constructor-arg name="age" value="28"/>
            <constructor-arg name="sex" value="男"/>
        </bean>

      test方法运行结果:

    UserModel{name='null', age=0, sex='null'}
    UserModel{name='通过静态工厂方法创建bean对象', age=28, sex='男'}

      三、通过实例工厂方法创建bean对象

      xml文件中增加配置,使用实例工厂方法,需要先创建工厂实例

    <!--实例工厂方法创建bean对象-->
        <!--工厂实例-->
        <bean id="userFactory" class="com.java.spring01.demo3.UserFactory"/>
        <bean id="user6" factory-bean="userFactory" factory-method="getUser1"/>
        <bean id="user7" factory-bean="userFactory" factory-method="getUser2">
            <constructor-arg name="name" value="通过实例工厂方法创建bean对象"/>
            <constructor-arg name="age" value="28"/>
            <constructor-arg name="sex" value="男"/>
        </bean>

      test方法运行结果:

    UserModel{name='null', age=0, sex='null'}
    UserModel{name='通过实例工厂方法创建bean对象', age=28, sex='男'}

      四、通过FactoryBean创建bean对象

      FactoryBean可以让spring容器通过这个接口的实现来创建我们需要的bean对象。

      创建FactoryBean的接口实现,其中isSingleton()方法用来设置是否是单例模式。单例模式,从spring容器中获取user8。每次的对象都是同一个实例。不是单例模式,模式获取Spring容器都会创建一个新对象。

    public class UserFactoryBean implements FactoryBean<UserModel> {
        int count = 1;
        @Override
        public UserModel getObject() throws Exception {
            UserModel userModel = new UserModel();
            userModel.setName("通过FactoryBean创建的第"+ count++ +"实例!");
            return userModel;
        }
    
        @Override
        public Class<?> getObjectType() {
            return UserModel.class;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    }

      单例模式的test方法运行结果:

    FactoryBean的调用分割线------
    UserModel{name='通过FactoryBean创建的第1实例!', age=0, sex='null'}
    UserModel{name='通过FactoryBean创建的第1实例!', age=0, sex='null'}

      非单例模式的test方法有运行结果:

    FactoryBean的调用分割线------
    调用无参构造方法初始化实例对象
    UserModel{name='通过FactoryBean创建的第2实例!', age=0, sex='null'}
    调用无参构造方法初始化实例对象
    UserModel{name='通过FactoryBean创建的第3实例!', age=0, sex='null'}
  • 相关阅读:
    C#中调用DTS
    经典问题:向setTimeout传递函数参数
    C#.NET 中的类型转换
    SQL语句导入导出大全 (转载)
    js脚本defer的作用
    [转]使用 Java API 处理 WebSphere MQ 大消息
    WideCharToMultiByte 宽字节转换为多字节
    [原].NET数据库开发中请注意区域时间格式
    输出页眉和页脚的简单HTTP模块实践
    浅析ASP.NET HTTP Module
  • 原文地址:https://www.cnblogs.com/8593l/p/12844257.html
Copyright © 2020-2023  润新知