区别
BeanFactory是接口,提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范.
FactoryBean也是接口,为IOC容器中Bean的实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式
BeanFactory
BeanFactory是spring的ioc工厂,负责管理所有的bean
DefaultListableBeanFactory,XmlBeanFactory,ApplicationContext 等具体实现类
另一个ioc工厂是ApplicationContext,他包含了BeanFactory所有的功能,并且增强了以下的功能
• MessageSource, 提供国际化的消息访问
• 资源访问,如URL和文件
• 事件传播
• 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层;
具体的实现类有ClassPathXmlApplicationContext,AnnotationConfigApplicationContext等
FactoryBean
案例
public interface UserService {
void test();
void setStr(String str);
}
@Service
public class UserServiceImpl implements UserService {
private String str;
public void setStr(String str) {
this.str = str;
}
public void test() {
System.out.println("UserServiceImpl----test" + str);
}
}
@Component
public class MyFactoryBean implements FactoryBean {
public Object getObject() throws Exception {
UserService userService = new UserServiceImpl();
userService.setStr("你好");
return userService;
}
public Class<?> getObjectType() {
return UserServiceImpl.class;
}
public boolean isSingleton() {
return true;
}
}
@Configuration
@ComponentScan("com.study")
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Test.class);
UserServiceImpl myFactoryBean = (UserServiceImpl) context.getBean("myFactoryBean");
System.out.println(myFactoryBean);
myFactoryBean.test();
FactoryBean bean = (FactoryBean) context.getBean("&myFactoryBean");
System.out.println(bean);
UserServiceImpl userService = (UserServiceImpl) context.getBean("userServiceImpl");
userService.test();
}
}
// 输出结果
com.study.service.impl.UserServiceImpl@35aea049
UserServiceImpl----test你好
com.study.service.impl.MyFactoryBean@7205765b
UserServiceImpl----testnull
分析
-
MyFactoryBean实现了FactoryBean,他的getObject()返回的是UserServiceImpl,如果直接ioc容器中getBean(“myFactoryBean”),取得的是UserServiceImpl,并且已经对其中的成员变量str赋值.
-
如果想取得MyFactoryBean他本身,就需要在ioc容器中getBean("&myFactoryBean"),就是加上’&’,spring底层去获取bean的时候其实会把’&'截取掉,会从另外一个map中去查找,所以最后取得的是MyFactoryBean对象
-
如果直接ioc容器中getBean(“userServiceImpl”),也可以取得UserServiceImpl对象,但是就没有对成员变量str进行赋值
-
FactoryBean的优势在于他在将bean交给spring管理之前,就已经将其中的一些依赖关系,具体例子就比如MyBatis的SqlSessionFactoryBean.