Bean实例的创建通常有如下3中方式:
1、通过构造方法创建Bean
package com.test; public class Person { public Person() { System.out.println("Person 构造方法"); } private Hobby hobby; public void setHobby(Hobby hobby) { System.out.println("通过依赖关系注入"); this.hobby = hobby; } public void singASong() { System.out.println(hobby.doIt()); } } interface Hobby { public String doIt(); } class Sing implements Hobby { public Sing() { System.out.println("Sing 构造方法"); } public String doIt() { return "I am singing."; } }
package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); Person p = ctx.getBean("person", Person.class); p.singASong(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="person" class="com.test.Person"> <property name="hobby" ref="hobbySing"></property> </bean> <bean id="hobbySing" class="com.test.Sing"></bean> </beans>
2、使用静态工厂方法创建Bean
package com.test2; public class PersonCreator { public static People createPerson(String type) { if (type.equals("chn")) { return new Chinese(); } if (type.equals("jpn")) { return new Japanese(); } return null; } }
package com.test2; public interface People { public void say(); } class Chinese implements People { public void say() { System.out.println("I am Chinese."); } } class Japanese implements People { public void say() { System.out.println("I am Japanese."); } }
工厂方法一定要static
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 静态工厂方法 --> <bean id="chinese" class="com.test2.PersonCreator" factory-method="createPerson"> <constructor-arg value="chn" /> </bean> <bean id="japanese" class="com.test2.PersonCreator" factory-method="createPerson"> <constructor-arg value="jpn" /> </bean> </beans>
package com.test2; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); People chn = ctx.getBean("chinese", People.class); chn.say(); People jpn = ctx.getBean("japanese", People.class); jpn.say(); } }
输出:I am Chinese.
I am Japanese.
3、调用实例工厂方法创建Bean
注:实例工厂方法与静态工厂方法只有一点不同
静态工厂方法:只需使用工厂类即可,工厂方法必须static
实例工厂方法:必须使用工厂类的实例,工厂方法必须non-static
package com.test2; public class PersonCreator { public People createPerson(String type) { if (type.equals("chn")) { return new Chinese(); } if (type.equals("jpn")) { return new Japanese(); } return null; } }
package com.test2; public interface People { public void say(); } class Chinese implements People { public void say() { System.out.println("I am Chinese."); } } class Japanese implements People { public void say() { System.out.println("I am Japanese."); } }
package com.test2; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); People chn = ctx.getBean("chinese", People.class); chn.say(); People jpn = ctx.getBean("japanese", People.class); jpn.say(); } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 实例工厂方法 --> <bean id="creator" class="com.test2.PersonCreator"/> <bean id="chinese" factory-bean="creator" factory-method="createPerson"> <constructor-arg value="chn" /> </bean> <bean id="japanese" factory-bean="creator" factory-method="createPerson"> <constructor-arg value="jpn" /> </bean> </beans>
输出:
I am Chinese.
I am Japanese.
总结:大多数情况下,BeanFactory直接通过new关键字调用构造器来创建Bean实例,而class属性指定了Bean实例的实现类。因此,<bean .../>元素必须指定Bean实例的class属性,但这并不是唯一的实例化Bean的方法。
使用实例工厂方法创建Bean实例,以及使用子Bean方法创建Bean实例时,都可以不指定class属性。