Spring支持如下三种方式创建Bean

1:调用构造器创建Bean

2:调用静态工厂方法创建Bean

3:调用实例工厂方法创建Bean

一:调用构造方法创建Bean

  调用构造方法创建Bean是最常用的一种情况Spring容器通过new关键字调用构造器来创建Bean实例,通过class属性指定Bean实例的实现类,也就是说,如果使用构造器创建Bean方法,则<bean/>元素必须指定class属性,其实Spring容器也就是相当于通过实现类new了一个Bean实例。调用构造方法创建Bean实例,通过名字也可以看出,我们需要为该Bean类提供无参数的构造器。下面是一个通过构造方法创建Bean的最简单实例

1:Bean实例实现类 Person.java

[java]  view plain  copy
  1. package com.mao.gouzao;  
  2.   
  3. public class Person   
  4. {  
  5.     private String name;  
  6.   
  7.     public Person(String name) 
  8. this.name=name;  
  9.     {  
  10.         System.out.println("Spring容器开始通过无参构造器创建Bean实例------------");  
  11.     }  
  12.     
  13.     public void input()  
  14.     {  
  15.         System.out.println("欢迎来到我的博客:"+name);  
  16.     }  
  17.   
  18. }  

因为是通过构造函数创建Bean,因此我们需要提供无参数构造函数,另外我们定义了一个name属性,并提供了setter方法,Spring容器通过该方法为name属性注入参数。

2:配置文件beans.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">  
  6.     <!-- 指定class属性,通过构造方法创建Bean实例 -->  
  7.     <bean id="person" class="com.mao.gouzao.Person">  
  8.       <!-- 通过构造方法赋值 -->  
  9.      <constructor-arg name="name" value="魔术师"></constructor-arg>  
  10.     </bean>  
  11. </beans>  
配置文件中,通过<bean>元素的id属性指定该bean的唯一名称,class属性指定该bean的实现类,可以理解成Spring容器就是通过该实现类new了一个Bean。通过<constructor-arg>标签的name属性和value属性指定了:构造方法赋值。

3:测试类 PersonTest.java

[java]  view plain  copy
  1. import org.springframework.context.ApplicationContext;  
  2. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  3.   
  4. public class PersonTest   
  5. {  
  6.     public static void main(String[]args)  
  7.     {  
  8.         //创建Spring容器  
  9.         ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");  
  10.         //通过getBean()方法获取Bean实例  
  11.         Person person=(Person) ctx.getBean("person");  
  12.         person.input();  
  13.     }  
  14. }  

4:运行结果


二:调用静态工厂方法创建Bean

   通过静态工厂创建Bean,是不是听着高大上了?顾名思义,咱们把创建Bean的任务交给了静态工厂,而不是构造函数,这个静态工厂就是一个Java类,那么使用静态工厂创建Bean咱们又需要添加哪些属性呢?我们同样需要在<bean/>元素内添加class属性,上面也说了,静态工厂是一个Java类,那么该class属性指定的就是该工厂的实现类,而不再是Bean的实现类,告诉Spring这个Bean应该由哪个静态工厂创建,另外我们还需要添加factory-method属性来指定由工厂的哪个方法来创建Bean实例,因此使用静态工厂方法创建Bean实例需要为<bean/>元素指定如下属性:
class:指定静态工厂的实现类,告诉Spring该Bean实例应该由哪个静态工厂创建(指定工厂地址)
factory-method:指定由静态工厂的哪个方法创建该Bean实例(指定由工厂的哪个车间创建Bean)
如果静态工厂方法需要参数,则使用<constructor-arg.../>元素传入
下面是一个简单的通过静态工厂方法创建Bean

1:首先我们定义一个Person的接口,定义一个说话的方法say()。 Person.java

[java]  view plain  copy
  1. package com.mao.staticFactory;  
  2.   
  3. public interface Person   
  4. {  
  5.     public void say();  
  6. }  
在程序中,我们尽量将一些特殊方法抽象出来定义成接口,在后面的程序中需要此方法,或者说具备此功能的时候,咱们直接实现该接口,以面向接口的方式完成某些功能。

2:Chinese Bean实现类Chinese.java

[java]  view plain  copy
  1. package com.mao.staticFactory;  
  2.   
  3. public class Chinese implements Person  
  4. {  
  5.     private String msg;  
  6.     //提供setter方法  
  7.     public void setMsg(String msg)   
  8.     {  
  9.         this.msg = msg;  
  10.     }  
  11.     @Override  
  12.     public void say()   
  13.     {  
  14.         // TODO Auto-generated method stub  
  15.         System.out.println(msg+",打倒一切美帝国主义");  
  16.     }  
  17.   
  18. }  
Chinese类实现了Person接口,完成了方法的实现,并定义了一个msg属性,提供了相应的setter方法,Spring通过该方法完成msg属性的参数值注入。

3:American Bean实现类American.java

[java]  view plain  copy
  1. package com.mao.staticFactory;  
  2.   
  3. public class American implements Person  
  4. {  
  5.     private String msg;  
  6.     //提供setter方法  
  7.     public void setMsg(String msg)   
  8.     {  
  9.         this.msg = msg;  
  10.     }  
  11.     @Override  
  12.     public void say()   
  13.     {  
  14.         // TODO Auto-generated method stub  
  15.         System.out.println(msg+",我要重返亚太地区");  
  16.     }  
  17.       
  18. }  

与Chinese Bean实例没太大的区别,

4:重点来了 配置文件 beans.xml

[html]  view plain  copy
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">  
  6.         <!-- 定义chinese Bean 由PersonFactory工厂的getPerson方法创建 -->  
  7.     <bean id="chinese" class="com.mao.staticFactory.PersonFactory" factory-method="getPerson">  
  8.       <!-- 为静态工厂的getPerson()方法传参 -->  
  9.       <constructor-arg value="chinese"/>  
  10.       <!-- 调用setMsg()方法为msg属性注入参数值 -->  
  11.       <property name="msg" value="我是中国人"/>  
  12.     </bean>     
  13.     <!-- 创建american Bean -->  
  14.     <bean id="american" class="com.mao.staticFactory.PersonFactory" factory-method="getPerson">  
  15.       <constructor-arg value="american"/>  
  16.       <property name="msg" value="我是美国人"></property>  
  17.        </bean>  
  18. </beans>  
拿chinese Bean来讲,配置文件中,通过<bean>元素的 class属性指定了,静态工厂的实现类,通过factory-method指定由静态工厂的哪个方法创建,也就是通过PersonFactory这个静态工厂的getPerson()方法创建,并且通过<constructor-arg.../>元素为该方法传入了一个chinese的参数。

5:静态工厂 PersonFactory.java

[java]  view plain  copy
  1. package com.mao.staticFactory;  
  2.   
  3. public class PersonFactory {  
  4.     public static Person getPerson(String arg)  
  5.     {  
  6.     if(arg.equalsIgnoreCase("chinese"))  
  7.     {  
  8.         return new Chinese();  
  9.     }     
  10.     else  
  11.     {  
  12.         return new American();  
  13.     }  
  14.   }  
  15. }  
静态工厂类的getPerson()方法就是通过咱们传入的相应参数来创建相应的Bean实体,然后返回相应实体。

6:主函数测试类 PersonTest.java

[java]  view plain  copy
  1. package com.mao.staticFactory;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class PersonTest   
  7. {  
  8.     public static void main(String []args)  
  9.     {  
  10.         //创建容器  
  11.         ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");  
  12.         //获取相应实体  
  13.         Chinese c=(Chinese) ctx.getBean("chinese" , Person.class);  
  14.         c.say();  
  15.         American a=(American) ctx.getBean("american" , Person.class);  
  16.         a.say();  
  17.     }  
  18. }  

7:运行结果:



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

   首先咱们再顾名思义一下哈,静态工厂通过class指定静态工厂实现类然后通过相应的方法创建即可,调用实例工厂则需要先创建该工厂的Bean实例,然后引用该实例工厂Bean的id创建其他Bean,在实例工厂中通过factory-bean指定工厂Bean的实例,在调用实例化工厂方法中,不用在<bean/>中指定class属性,因为这时,咱们不用直接实例化该Bean,而是通过调用实例化工厂的方法,创建Bean实例,调用实例化工厂需要为<bean/>指定一下两个属性
factory-bean :该属性指定工厂Bean的id
factory-method:该属性指定实例工厂的工厂方法。
下面是我们将上面调用静态方法的例子稍微改一下

仅需将配置文件beans.xml修改为:

[html]  view plain  copy
  1. <?xml version="1.0" encoding="GBK"?>  
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xmlns="http://www.springframework.org/schema/beans"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.     http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">  
  6.         <!-- 配置工厂Bean,class指定该工厂的实现类,该Bean负责产生其他Bean实例 -->  
  7.     <bean id="personFactory" class="com.mao.instanceFactory.PersonFactory"/>  
  8.     <!-- 由实例工厂Bean的getPerson()方法,创建Chinese Bean, -->  
  9.     <bean id="ch" factory-bean="personFactory" factory-method="getPerson">  
  10.       <!-- 为该方法传入参数为chinese -->  
  11.       <constructor-arg value="chinese"/>  
  12.     </bean>  
  13.     <!-- 由实例工厂Bean的getPerson()方法,创建American Bean, -->  
  14.     <bean id="usa" factory-bean="personFactory" factory-method="getPerson">  
  15.       <constructor-arg value="american"></constructor-arg>  
  16.     </bean>  
  17. </beans>  

运行结果是一样的:


调用实例工厂创建Bean和调用静态工厂的区别

   其实调用实例工厂创建Bean和调用静态工厂创建Bean的区别就在于,调用实例工厂将工厂单独拿了出来(先实例化工厂)创建一个工厂Bean,通过工厂<bean>的class属性指定工厂的实现类,然后再需要创建其他Bean时,只需要在该<bean/>元素添加factory-bean、factory-method指定该Bean是有哪个实例工厂的哪个方法创建就可以了,放在现实生活中就是:我们先找一个地方创建一个工厂,id指定工厂注册名字(xxx有限公司),class指定公司所在地,工厂里面有车间(创造其他Bean的方法),那好有了工厂我们再需要创建其他Bean时,只需要指定这个Bean是由,哪个工厂的哪个车间创建的即可,也就是 只需要在该<bean/>元素添加factory-bean、factory-method属性即可
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐