spring 的BeanFactory包含了最基本的bean操作,像通过bean name 来获取bean,判断bean是否存在等等。这些可以具体去看,不详述,主要看看‘&’ 操作符。
‘&’操作符的作用在文中的描述是:如果一个Bean是一个FactoryBean的话,加上'&'符号可以得到FactoryBean本身,那什么是FactoryBean?
我原来以为像在XML中配置的factory-method中的那个Bean可以通过‘&’符号来得到,但是spring报告的错误明显告诉我不是这样的。
下面是错误代码:
public class FactoryBean {
public static void main(String...strings){
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext();
ac.setConfigLocation("factoryBean.xml");
ac.refresh();
String s=(String)ac.getBean("factoryBean");
Object o=ac.getBean("&factoryBean");
System.out.println(s);
System.out.println(o instanceof FactoryBean);
}
public static String newInstance(){
return new String("asdf");
}
}
XML文件:
<?xml version="1.0" ?>
<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-3.1.xsd">
<bean id="factoryBean" class="liufq.FactoryBean" factory-method="newInstance"></bean>
</beans>
运行之后报错
Exception in thread "main" org.springframework.beans.factory.BeanIsNotAFactoryException: Bean named 'factoryBean' must be of type [org.springframework.beans.factory.FactoryBean], but was actually of type [java.lang.String]
at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1420)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:248)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1098)
at liufq.FactoryBean.main(FactoryBean.java:11)
看来FactoryBean不是每个bean都能当的,上网搜了一下发现,只有继承了spring给的接口org.springframework.beans.factory.FactoryBean<T>才能算是一个FactoryBean,也就是说,spring通过接口限定了工厂bean的条件,T就是在XML中配置后返回的bean类型。
且看代码:
public class FactoryBean implements org.springframework.beans.factory.FactoryBean<String>{
public static void main(String...strings){
ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext();
ac.setConfigLocation("factoryBean.xml");
ac.refresh();
String s=(String)ac.getBean("factoryBean");
Object o=ac.getBean("&factoryBean");
System.out.println(s);
System.out.println(o instanceof FactoryBean);
}
public static String newInstance(){
return new String("asdf");
}
@Override
public String getObject() throws Exception {
// TODO Auto-generated method stub
return "aaaa";
}
@Override
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isSingleton() {
// TODO Auto-generated method stub
return false;
}
XML文件把factory-method去掉就行了,不去掉的话还是会报一样的错误,因为返回的类型是String,而不是FactoryBean通过getObject返回的实例。
那用FactoryBean有什么好处呢,原本Bean的生成交给了FactoryBean来代理,可以在bean的返回前做一些初始化工作,或者日志输出等有帮助的信息,而在bean初始化完成后也可以作相应的日志,资源等处理,使bean生成变得更加灵活,而且还可以配置bean的scope等信息。spring的aop功能before和after是可以用FactoryBean代理出来的。