理解spring中的BeanFactory和FactoryBean的区别与联系
2018-02-02 11:13
609 查看
原文地址:http://blog.csdn.net/joenqc/article/details/66479154
首先,这俩都是个接口…
实现
而 实现
一个Bean想要实现
1
2
3
4
5
有一点需要注意,如果将一个实现了FactoryBean的类成功配置到了spring上下文中,那么通过该类对象的名称(比如appleFactoryBean)从spring的applicationContext或者beanFactory获取bean时,获取到的是appleFactoryBean创建的apple实例,而不是appleFactoryBean自己,如果想通过spring拿到appleFactoryBean,需要在名称前加
1
这个prefix在BeanFactory接口源码中有提到:
1
2
3
4
5
6
7
还有一点需要注意,FactoryBean管理的bean实际上也是由spring进行配置、实例化、管理,因此由FactoryBean管理的bean不能再次配置到spring配置文件中(xml、java类配置、注解均不可以),否则会报如下异常:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
附上一个例子:
spring配置类:
1
2
3
4
AppleBean :
1
2
3
4
AppleFactoryBean :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
启动类 :
首先,这俩都是个接口…
实现
BeanFactory接口的类表明此类事一个工厂,作用就是配置、新建、管理 各种Bean。
而 实现
FactoryBean的类表明此类也是一个Bean,类型为工厂Bean(Spring中共有两种bean,一种为普通bean,另一种则为工厂bean)。顾名思义,它也是用来管理Bean的,而它本身由spring管理。
一个Bean想要实现
FactoryBean,必须实现以下三个接口:
1. Object getObject():返回由FactoryBean创建的Bean的实例 2. boolean isSingleton():确定由FactoryBean创建的Bean的作用域是singleton还是prototype; 3. getObjectType():返回FactoryBean创建的Bean的类型。
1
2
3
4
5
有一点需要注意,如果将一个实现了FactoryBean的类成功配置到了spring上下文中,那么通过该类对象的名称(比如appleFactoryBean)从spring的applicationContext或者beanFactory获取bean时,获取到的是appleFactoryBean创建的apple实例,而不是appleFactoryBean自己,如果想通过spring拿到appleFactoryBean,需要在名称前加
&符号 :
out.println(applicationContext.getBean("&appleFactoryBean"))
1
这个prefix在BeanFactory接口源码中有提到:
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */ String FACTORY_BEAN_PREFIX = "&";
1
2
3
4
5
6
7
还有一点需要注意,FactoryBean管理的bean实际上也是由spring进行配置、实例化、管理,因此由FactoryBean管理的bean不能再次配置到spring配置文件中(xml、java类配置、注解均不可以),否则会报如下异常:
Exception in thread "main" org.springframework.beans.factory.BeanIsNotAFactoryException: Bean named 'appleFactoryBean' is expected to be of type 'org.springframework.beans.factory.FactoryBean' but was actually of type 'java.lang.Object' at org.springframework.beans.factory.support.AbstractBeanFactory.getObjectForBeanInstance(AbstractBeanFactory.java:1612) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:317) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:742) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:866) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:542) at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84) at com.joen.testspringcontainer.Start.main(Start.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
附上一个例子:
spring配置类:
@Configuration @ComponentScan public class Configurations { }
1
2
3
4
AppleBean :
//@Component 这里不可以加注解 !!!!!! public class AppleBean{ }
1
2
3
4
AppleFactoryBean :
@Component public class AppleFactoryBean implements FactoryBean{ public Object getObject() throws Exception { return new AppleBean(); } public Class<?> getObjectType() { return AppleBean.class; } public boolean isSingleton() { return false; } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
启动类 :
public class Start { public static void main(String[] args){ ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Configurations.class); out.println(applicationContext.getBean("appleFactoryBean"));//得到的是apple out.println(applicationContext.getBean("&appleFactoryBean"));//得到的是apple工厂 } }
相关文章推荐
- 理解spring中的BeanFactory和FactoryBean的区别与联系
- 理解spring中的BeanFactory和FactoryBean的区别与联系
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- Spring中的beanFactory和applicationContext的联系和区别
- spring几种依赖注入方式以及ref-local/bean,factory-bean,factory-method区别联系
- 【Spring】普通bean、FactoryBean、BeanFactory的区别与联系
- Spring中的beanFactory和applicationContext的联系和区别
- BeanFactory和ApplicationContext联系和区别
- Spring中BeanFactory和ApplicationContext的区别
- spring中的BeanFactory与ApplicationContext的作用和区别?
- Spring集成Hibernate 理解LocalSessionFactoryBean
- spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别
- Spring中的BeanFactory和FactoryBean的区别
- Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 ApplicationContext和BeanFactory区别