不同Bean创建方式以及对应配置

《整合SSH应用开发详解》读后笔记

不同Bean创建方式有三种: 
1、大多数情况下,BeanFactory使用new关键字调用构造器 
2、BeanFactory调用某个类的静态工厂方法创建Bean 
3、BeanFactory调用实例工厂方法创建Bean

一、使用new关键字调用构造器

使用new关键字来创建Bean实例是最常见的情形,如果采用设值注入的方式,要求类提供无参数的构造器。

BeanFactory调用默认构造器创建Bean实例,该实例是个默认的实例。所有的属性执行默认的初始化。接下来,BeanFactory会根据配置文件决定依赖关系,先实例化依赖的Bean,然后为Bean注入依赖关系,最后将一个完整的Bean示例返回给程序,该Bean示例的所有属性,已经由Spring容器完成了初始化。

调用Bean的接口和实现类:

public interface Person
{
	public void useAxe();
}
Person的实现类

public class Chinese implements Person
{
	private Axe axe;
	public Chinese()
	{
		System.out.println("Spring实例化主调bean:Chinese实例...");
	}
	public void setAxe(Axe axe)
	{
		System.out.println("Spring执行依赖关系注入...");
        this.axe = axe;
	}

	public void useAxe()
	{
		System.out.println(axe.chop());
	}
}
下面给出Person接口依赖Bean的接口和实现类Axe

public interface Axe
{
	public String chop();
}
Axe的实现类SteelAxe

public class SteelAxe implements Axe
{
	public SteelAxe()
	{
        System.out.println("Spring实例化依赖bean:SteelAxe实例...");
	}
	public String chop()
	{
		return "钢斧砍柴真快";
	}
}
Spring的配置文件如下:

<?xml version="1.0" encoding="GBK"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="steelAxe" class="lee.SteelAxe"/>
	<bean id="chinese" class="lee.Chinese">
		<property name="axe" ref="steelAxe"/>
    </bean>

</beans>
主程序如下

public class BeanTest
{
    public static void main(String[] args)throws Exception
    {
        //以CLASSPATH路径下的配置文件,创建ClassPathResource实例
        ClassPathResource isr = new ClassPathResource("bean.xml");
        //以Resource对象作为参数,创建BeanFactory的实例
        XmlBeanFactory factory = new XmlBeanFactory(isr);
        System.out.println("程序已经实例化BeanFactory...");
		Person p = (Person)factory.getBean("chinese");
        System.out.println("程序中已经完成了chinese bean的实例化...");
		p.useAxe();
    }
}

执行效果:

不同Bean创建方式以及对应配置_第1张图片

执行的结果清楚地反映了执行过程:

  • 程序创建BeanFactory实例
  • 调用Chinese类的默认构造器来创建默认实例
  • 根据配置文件注入依赖关系,先实例化依赖Bean,然后将依赖Bean注入
  • 返回一个完整的JavaBean实例

二、使用静态工厂方法创建Bean

使用静态工厂方法创建Bean实例时,class属性也是必需的,但此时class属性并不是该实例的实现类,而是静态工厂类。Spring需要知道由哪个工厂方法来创建Bean实例,使用factory-method属性来确定静态工厂方法名。Spring调用工程方法,并返回一个有效的对象。后面的过程,Spring的处理步骤与采用其他方法的创建完全一样。

下面Bean要通过factory-method指定的方法创建。注意,这个bean定义并没有bean实例的实现类,只指定静态工厂类。该工厂的工厂方法必须是静态的。如果静态工厂方法需要参数,使用<constructor-arg>元素传入即可。

Being接口

package lee;

public interface Being
{
	public void testBeing();
}

下面是接口的两个实现类。

Dog类

package lee;

public class Dog implements Being
{
	private String msg;
	public void setMsg(String msg)
	{
		this.msg = msg;
	}

	public void testBeing()
	{
		System.out.println(msg + "    狗爱啃骨头");
	}
}

Cat类

package lee;

public class Cat implements Being
{
	private String msg;
	public void setMsg(String msg)
	{
		this.msg = msg;
	}

	public void testBeing()
	{
		System.out.println(msg + "    猫喜欢吃老鼠");
	}
}

下面的工厂包含静态方法,静态方法可返回Being实例:

package lee;

public class BeingFactory
{
    public BeingFactory()
    {
        System.out.println("=======6");
    }
    public static Being getBeing(String arg) 
    {
		if (arg.equalsIgnoreCase("dog"))
		{
			return new Dog();
		}
		else
		{
			return new Cat();
		}
    }
}


下面是使用静态工厂方法创建Bean实例的配置文件

<?xml version="1.0" encoding="GBK"?>
<!-- 定义Spring配置文件的根元素,并指定Schema信息 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="dog" class="lee.BeingFactory" factory-method="getBeing">
		<constructor-arg value="dog"/>
		<property name="msg" value="我是狗"/>
	</bean>

	<bean id="cat" class="lee.BeingFactory" factory-method="getBeing">
		<constructor-arg value="cat"/>
		<property name="msg" value="我是猫"/>
	</bean>

</beans>

如此可以看出: 
1、class属性值并非是Bean的实现类,而是静态工厂类 
2、必须使用factory-method指定产生实例的静态工厂方法 
3、如果静态方法需要参数,数使用constructor-arg元素指定 


主程序如下

public class SpringTest 
{
    public static void main(String[] args)throws Exception
    {
        //以CLASSPATH路径下的配置文件,创建ClassPathResource实例
        ClassPathResource isr = new ClassPathResource("bean.xml");
        //以Resource对象作为参数,创建BeanFactory的实例
        XmlBeanFactory factory = new XmlBeanFactory(isr);
        System.out.println("程序已经实例化BeanFactory...");
		Being b1 = (Being)factory.getBean("dog");
		b1.testBeing();
		Being b2 = (Being)factory.getBean("cat");
		b2.testBeing();
    }
}

三、调用实例工厂方法创建Bean

实例工厂方法必须提供工厂实例,因此必须在配置文件中配置工厂实例。

采用实例工厂方法创建Bean的配置需要如下两个属性:

  • factory-bean,该属性的值为工程的Bean的id
  • factory-method,该方法负责生成Bean实例

Person接口

public interface Person
{
    public String sayHello(String name);
    public String sayGoodBye(String name);
}
两个Person实现类

American类

public class American implements Person
{
    public String sayHello(String name)
    {
        return name + ",Hello";
    }

    public String sayGoodBye(String name)
    {
        return name + ",Good Bye";
    }
}

Chinese类

public class Chinese implements Person
{
    public String sayHello(String name)
    {
        return name + ",您好";
    }

    public String sayGoodBye(String name)
    {
        return name + ",下次再见";
    }
}

Person工厂的代码

public class PersonFactory
{
    public Person getPerson(String ethnic)
    {
        if (ethnic.equalsIgnoreCase("chin"))
        {
            return new Chinese();
        }
        else
        {
            return new American();
        }

    }
}


Spring此时不负责创建Bean实例,而是产生Bean工厂实例。这是抽象工厂模式,Spring容器负责生成Bean实例,该Bean实例是其他实例的工厂,负责产生程序需要的Bean实例。

配置文件

<?xml version="1.0" encoding="GBK"?>
<!-- 定义Spring配置文件的根元素,并指定Schema信息 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="personFactory" class="lee.PersonFactory"/>

	<bean id="chinese" factory-bean="personFactory" factory-method="getPerson">
		<constructor-arg value="chin"/>
	</bean>

	<bean id="american" factory-bean="personFactory" factory-method="getPerson">
		<constructor-arg value="ame"/>
	</bean>


</beans>

主程序

public class SpringTest 
{
	public static void main(String[] args)throws Exception
    {
	//以CLASSPATH路径下的配置文件,创建ClassPathResource实例
	ClassPathResource isr = new ClassPathResource("bean.xml");
	//以Resource对象作为参数,创建BeanFactory的实例
	XmlBeanFactory factory = new XmlBeanFactory(isr);
        System.out.println("程序已经实例化BeanFactory...");
        Person p1 = (Person)factory.getBean("chinese");
        System.out.println(p1.sayHello("Mary"));
        System.out.println(p1.sayGoodBye("Mary"));
        Person p2 = (Person)factory.getBean("american");
        System.out.println(p2.sayHello("Jack"));
        System.out.println(p2.sayGoodBye("Jack"));
    }
}

第一种方法使用较少,第二和第三中方法很类似,主要区别如下:

不同Bean创建方式以及对应配置_第2张图片


你可能感兴趣的:(spring,bean,exception,String,Class,interface)