BeanFactory和FactoryBean是spring里的两个接口,区分他们关键看后面的单词,一个是生产Bean的工厂,一个工厂Bean。前者是生产spring整个IOC的工厂,所以它可以包含后者;后者仅仅作为特定bean的工厂,服务对象片面,主要用于代理,实现AOP用,比如CacheProxyFactoryBean。先看下这两个接口,再看下一个实例的代码:
BeanFactory:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String arg0) throws BeansException; <T> T getBean(String arg0, Class<T> arg1) throws BeansException; <T> T getBean(Class<T> arg0) throws BeansException; Object getBean(String arg0, Object... arg1) throws BeansException; boolean containsBean(String arg0); boolean isSingleton(String arg0) throws NoSuchBeanDefinitionException; boolean isPrototype(String arg0) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String arg0, Class<?> arg1) throws NoSuchBeanDefinitionException; Class<?> getType(String arg0) throws NoSuchBeanDefinitionException; String[] getAliases(String arg0); }
FactoryBean:
public interface FactoryBean<T> { T getObject() throws Exception; Class<?> getObjectType(); boolean isSingleton(); }
实例代码:
package spitter; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class Spitter { private long id; @NotNull @Size(min = 5, max = 16) private String firstName; @NotNull @Size(min = 5, max = 25) private String lastName; @NotNull @Size(min = 20, max = 30) private String username; @NotNull @Size(min = 2, max = 30) private String password; public Spitter(String firstName, String lastName, String username, String password) { this(0L, firstName, lastName, username, password); } public Spitter(long id, String firstName, String lastName, String username, String password) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.username = username; this.password = password; } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return firstName + username + lastName + ", " + password; }
package spitter; import org.springframework.beans.factory.FactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpitterFactoryBean implements FactoryBean<Spitter> { @Override public Spitter getObject() throws Exception { return new Spitter("Wu", "Feng", "Lin", "123456"); } @Override public Class<?> getObjectType() { return Spitter.class; } @Override public boolean isSingleton() { return true; } public static void main(String[] args) throws Exception { // 读取配置文件,加载ioc容器,ApplicationContext的顶层接口就是BeanFactory ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml"); // getBean也是BeanFactory里的接口 Spitter spitter = app.getBean("spitter", Spitter.class); System.out.printf("BeanFactory 生成的实例:%s ", spitter.toString()); System.out.printf("BeanFactory其他方法,是否包含bean:%b, 是否单例:%b ",app.containsBean("spitter"),app.isSingleton("spitter")); // 直接new实例化FactoryBean SpitterFactoryBean spitterFactory = new SpitterFactoryBean(); spitter = spitterFactory.getObject(); System.out.printf("FactoryBean 生成的实例:%s ", spitter.toString()); System.out.printf("FactoryBean其他方法,bean加载的类型:%s, 是否单例:%b ",spitterFactory.getObjectType(),spitterFactory.isSingleton()); // 通过BeanFactory实例化FactoryBean spitterFactory = (SpitterFactoryBean)app.getBean("&spitterFactoryBean"); System.out.printf("BeanFactory 生成FactoryBean,FactoryBean 生成的实例:%s ", spitter.toString()); } }
applicationContext.xml:必须放在webappsWEB-INFclasses目录下
<?xml version="1.0" encoding="UTF-8"?> <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="spitter" class="spitter.Spitter"> <constructor-arg value="Wu" /> <constructor-arg value="Shu" /> <constructor-arg value="Man" /> <constructor-arg value="654321" /> </bean> <bean id="spitterFactoryBean" class="spitter.SpitterFactoryBean" /> </beans>
运行结果:
三月 30, 2017 12:08:42 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2328c243: startup date [Thu Mar 30 00:08:42 CST 2017]; root of context hierarchy
三月 30, 2017 12:08:43 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
BeanFactory 生成的实例:WuManShu, 654321
BeanFactory其他方法,是否包含bean:true, 是否单例:true
FactoryBean 生成的实例:WuLinFeng, 123456
FactoryBean其他方法,bean加载的类型:class spitter.Spitter, 是否单例:true
BeanFactory 生成FactoryBean,FactoryBean 生成的实例:WuLinFeng, 123456