Spring IOC bean注册实例化

注册与实例化bean

通常在resource目录下创建以application开头的xml作为bean的元数据属性配置,通过定义来管理bean的注册和实例化。

set方法

<!-- 一个bean标签就表示一个对象, id:这个对象的唯一标识, name:类似别名, class:注册对象的完全限定名 -->
<!-- 使用setter注入,绑定方法名setXXX,name属性值必须与XXX一致,并且setter方法必须为public -->
<!-- 通过setter注入,实际是通过反射调用类的无参构造,所以在显示为类定义构造方法的时候不要忘记添加一个无参构造 -->
<bean id="person1" name="person" class="com.nanborone.bean.Person">
    <!-- 使用property标签给对象的属性赋值, name:表示属性的名称, value:表示属性的值 -->
    <property name="id" value="1"/>
    <property name="name" value="nanborone"/>
    <property name="male" value="true"/>
</bean>

构造方法

<!-- 使用constructor注入,绑定构造方法形参名XXX,name属性值必须与XXX一致 -->
<!-- constructor-arg个数必须与已有的构造器参数个数相同 -->
<bean id="person2" class="com.nanborone.bean.Person">
	<!-- 使用constructor-arg标签在对象构造的时候给属性赋值, name:表示属性的名称, value:表示属性的值 -->
	<!-- 在使用构造器赋值的时候可以省略name属性,但是此时就要求必须严格按照构造器参数的顺序来填写了 -->
	<!-- 如果name属性省略且有相同参数个数的构造器,后定义的会覆盖先定义的除非指定type来匹配确定的构造器 -->
    <constructor-arg name="id" value="2"/>
    <constructor-arg name="name" value="nanborone"/>
    <constructor-arg name="male" value="true"/>
</bean>
<bean id="person3" class="com.nanborone.bean.Person">
	<!-- 如果想不按照顺序来添加参数值,那么可以搭配index属性来使用 -->
    <constructor-arg value="3"/>
    <constructor-arg value="true" index="2"/>
    <constructor-arg value="nanborone" index="1"/>
</bean>
<bean id="person4" class="com.nanborone.bean.Person">
	<!-- 可以使用type属性来指定类型,但是无法自动拆装箱,可以用type="int" -->
    <constructor-arg value="4" type="int"/>
    <constructor-arg value="nanborone" type="java.lang.String"/>
    <constructor-arg value="true" index="2"/>
</bean>

Spring也可以将String转成默认的Java内置类型。例如int, long, String, boolean等,通过StringToXXXConverter 。

通常情况下我们只使用最简单的属性注入方式,最简单的构造器注入偶尔也会使用,剩下的加乱七八糟属性的基本不用。

工厂模式

在之前的案例中,所有bean对象的创建都是通过反射得到对应的bean实例,其实在spring中还包含另外一种创建bean实例的方式,就是通过工厂模式进行对象的创建。

<!-- 静态工厂:不需要创建工厂类实例,通过类方法(静态方法)来获得bean -->
<!-- class:指定静态工厂类, factory-method:指定哪个方法是工厂方法 -->
<bean id="person1" class="com.nanborone.bean.factory.PersonStaticFactory" factory-method="getInstance">
    <!--constructor-arg:可以为方法指定参数-->
    <constructor-arg value="nanborone" />
</bean>

<!-- 实例工厂:需要先创建工厂类实例,再通过实例调用实例方法来获得bean-->
<bean id="personInstanceFactory" class="com.nanborone.bean.factory.PersonInstanceFactory" />
<!-- factory-bean:指定使用哪个工厂实例, factory-method:指定使用哪个工厂实例的方法 -->
<bean id="person2" class="com.nanborone.bean.Person" factory-bean="personInstanceFactory" factory-method="getInstance">
    <constructor-arg value="nanborone" />
</bean>

创建对应的静态工厂类和实例工厂类:

public class PersonStaticFactory {
    public static Person getInstance(String name) {
        return new Person(1, name, true);
    }
}
public class PersonInstanceFactory {
    public Person getInstance(String name) {
        return new Person(1, name, true);
    }
}

FactoryBean

FactoryBean是Spring规定的一个接口,当前接口的实现类,Spring都会将其作为一个工厂,但是在Ioc容器启动的时候不会创建实例,只有在使用的时候才会创建对象,无论是不是单例的。

<bean id="myFactoryBean" class="com.nanborone.bean.factorybean.MyFactoryBean" />

创建MyFactoryBean类:

public class MyFactoryBean implements FactoryBean<Person> {

	// 工厂方法,返回需要创建的对象
    @Override
    public Person getObject() throws Exception {
        System.out.println("通过MyFactoryBean创建");
        return new Person(1, "nanborone, true);
    }

    // 返回创建对象的类型,spring会自动调用该方法返回对象的类型
    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }

    // 创建的对象是否是单例对象
    @Override
    public boolean isSingleton() {
        return false;
    }
}

测试的时候需要通过myFactoryBean来获得person实例

public class IocTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        Person person = context.getBean("myfactorybean", Person.class);
        System.out.println(person);
    }
}

发布了13 篇原创文章 · 获赞 0 · 访问量 334

猜你喜欢

转载自blog.csdn.net/weixin_44601009/article/details/104309975