Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法

1. BeanFactory

  BeanFactory,以Factory结尾,表示它是一个工厂类(接口),用于管理Bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

  Spring为我们提供了许多易用的BeanFactory实现,XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。

  实例化容器

1 Resource resource = new FileSystemResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
1 ClassPathResource resource = new ClassPathResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
3 BeanFactory factory = (BeanFactory) context;

基本就是这些了,接着使用getBean(String beanName)方法就可以取得bean的实例;BeanFactory提供的方法及其简单,仅提供了六种方法供客户调用:

  •   boolean containsBean(String beanName) 判断工厂中是否包含给定名称的bean定义,若有则返回true
  •   Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
  •   Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
  •   Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常
  •   boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
  •   String[] getAliases(String name) 返回给定bean名称的所有别名

2. FactoryBean

  以Bean结尾,表示它是一个Bean,不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的ID从FactoryBean中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

  例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。

 1 /**
 2  * my factory bean<p>
 3  * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出
 4  * @author daniel.zhao
 5  *
 6  */
 7 public class MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean {
 8
 9     private static final Logger logger = LoggerFactory.getLogger(MyFactoryBean.class);
10
11     private String interfaceName;
12
13     private Object target;
14
15     private Object proxyObj;
16
17     @Override
18     public void destroy() throws Exception {
19         logger.debug("destroy......");
20     }
21
22     @Override
23     public void afterPropertiesSet() throws Exception {
24         proxyObj = Proxy.newProxyInstance(
25                 this.getClass().getClassLoader(),
26                 new Class[] { Class.forName(interfaceName) },
27                 new InvocationHandler() {
28
29             @Override
30             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
31                 logger.debug("invoke method......" + method.getName());
32                 logger.debug("invoke method before......" + System.currentTimeMillis());
33                 Object result = method.invoke(target, args);
34                 logger.debug("invoke method after......" + System.currentTimeMillis());
35                 return result;
36             }
37
38         });
39         logger.debug("afterPropertiesSet......");
40     }
41
42     @Override
43     public Object getObject() throws Exception {
44         logger.debug("getObject......");
45         return proxyObj;
46     }
47
48     @Override
49     public Class<?> getObjectType() {
50         return proxyObj == null ? Object.class : proxyObj.getClass();
51     }
52
53     @Override
54     public boolean isSingleton() {
55         return true;
56     }
57
58     public String getInterfaceName() {
59         return interfaceName;
60     }
61
62     public void setInterfaceName(String interfaceName) {
63         this.interfaceName = interfaceName;
64     }
65
66     public Object getTarget() {
67         return target;
68     }
69
70     public void setTarget(Object target) {
71         this.target = target;
72     }
73
74     public Object getProxyObj() {
75         return proxyObj;
76     }
77
78     public void setProxyObj(Object proxyObj) {
79         this.proxyObj = proxyObj;
80     }
81
82 }

XML-Bean配置如下

1 <bean id="fbHelloWorldService" class="com.ebao.xxx.MyFactoryBean">
2     <property name="interfaceName" value="com.ebao.xxx.HelloWorldService" />
3     <property name="target" ref="helloWorldService" />
4 </bean>

Junit Test class

 1 @RunWith(JUnit4ClassRunner.class)
 2 @ContextConfiguration(classes = { MyFactoryBeanConfig.class })
 3 public class MyFactoryBeanTest {
 4
 5     @Autowired
 6     private ApplicationContext context;
 7
 8     /**
 9      * 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理
10      * 从ApplicationContext中获取自定义的FactoryBean
11      * context.getBean(String beanName) ---> 最终获取到的Object是FactoryBean.getObejct(),
12      * 使用Proxy.newInstance生成service的代理类
13      */
14     @Test
15     public void testFactoryBean() {
16         HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService");
17         helloWorldService.getBeanName();
18         helloWorldService.sayHello();
19     }
20 }

其实FactoryBean这栋特点,可以实现很多有用的功能,实现大家多多评论多多补充,一起探讨。

原文地址:https://www.cnblogs.com/daxiong225/p/9534991.html

时间: 2024-10-09 22:51:34

Spring BeanFactory与FactoryBean的区别及其各自的详细介绍于用法的相关文章

Spring中BeanFactory与FactoryBean的区别

在Spring中有BeanFactory和FactoryBean这2个接口,从名字来看很相似,比较容易搞混. 一.BeanFactory BeanFactory是一个接口,它是Spring中工厂的顶层规范,是SpringIoc容器的核心接口,它定义了getBean().containsBean()等管理Bean的通用方法.Spring的容器都是它的具体实现如: DefaultListableBeanFactory XmlBeanFactory ApplicationContext 这些实现类又从

Spring中的BeanFactory和FactoryBean的区别

一句话介绍 BeanFactory接口用来生产Bean,它处理生产bean的接口体系的最顶层,getBean方法可以获取bean.FactoryBean接口用来定制Bean的生产过程,getObject方法中可以实现自定义过程. 源码 BeanFactory源码 public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String var1) throws BeansExce

BeanFactory与FactoryBean的区别

有很多常用的FactoryBean类: 1.org.springframework.scheduling.quartz.SchedulerFactoryBean 2.org.springframework.scheduling.quartz.CronTriggerFactoryBean 3.org.springframework.scheduling.quartz.SimpleTriggerFactoryBean 4.org.springframework.scheduling.quartz.J

Spring中BeanFactory和ApplicationContext的区别

我用一个例子去测试BeanFactory和ApplicationContext的区别 首先建立一个bean public class User {//声明无参构造,打印一句话,监测对象创建时机 public User(){ System.out.println("User对象初始化"); } } 然后再建立测试类 public class UserTest { @Test public void ApplicationContexttest(){ ApplicationContext

Spring BeanFactory 中的类型推断

Spring BeanFactory 中的类型推断 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Spring 容器中可以根据 beanName 查找其类型,其推断方式和 bean 的创建方式密切相关,并且 Spring 中有一个原则是尽可能的不要通过创建 bean 来获取其类型,除了 FactoryBean 只有通过创建对象调用其 getObjectType 方法,但也只是部分的创建该 FactoryBean(所谓

Spring BeanFactory 依赖注入

Spring BeanFactory 依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.autowire 五种注入方式测试 (1) 环境准备 public class Company { private Department department; private List<Employee> employees; public Company() { } public Company(Departmen

Spring MVC与struts2的区别

Spring MVC与struts2的区别: 1.易用性Spring MVC上手简单,并且可以与Spring无缝结合,毕竟都是一个公司的产品,学习起来也比较简单,比如从前端给对象填充值,他的处理就比Struts2简单多了,再比如对Restful风格的URL的支持,这些Spring MVC都比Struts2做的好N倍. 2.安全性说到安全性,现在又爆出了上述漏洞.Spring MVC到目前为止还没有发现比较严重的漏洞. 3.可扩展性Spring MVC依靠Spring这颗大树,Spring的实力我

攻城狮在路上(贰) Spring(四)--- Spring BeanFactory简介

BeanFactory时Spring框架最核心的接口,它提供了高级IoC的配置机制,使管理不同类型的Java对象成为了可能.我们一般称BeanFactory为IoC容器.BeanFactory是Spring的基础设施,面向Spring本身. 一.BeanFactory的体系结构: 二.类图说明: ListableBeanFactory:定义了访问容器中Bean基本信息的方法,查看Bean的个数.获取某一类型Bean的配置名,看容器中是否包含某一Bean等方法. HierarchicalBeanF

bean创建过程、spring BeanFactory的实现、spring aware

Bean的创建过程: Spring beanFactory的工厂模式实现: 解析<bean>标签,存到一个Map<String, Object> beans中 People o = (People)factory.getBean("p"); 因为map存的是object类型,所以取出时需要强制类型转换 Bean的生命周期: spring aware的目的是为了让Bean获得spring容器的服务,bean继承applicationContextAware可以获得