SpringBeanFactory与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从BeanFactory中获取的实际上是FactoryBean的getObject()返回的对象,而不是FactoryBean本身,如果要获取FactoryBean对象,请在id前面加一个&符号来获取。

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

 1/**

2 * my factory bean<p>

3 * 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出

4 * @author daniel.zhao

5 *

6*/

7publicclass MyFactoryBean implements FactoryBean<Object>, InitializingBean, DisposableBean {

8

9privatestaticfinal Logger logger = LoggerFactory.getLogger(MyFactoryBean.class);

10

11private String interfaceName;

12

13private Object target;

14

15private Object proxyObj;

16

17 @Override

18publicvoid destroy() throws Exception {

19 logger.debug("destroy......");

20 }

21

22 @Override

23publicvoid afterPropertiesSet() throws Exception {

24 proxyObj = Proxy.newProxyInstance(

25this.getClass().getClassLoader(),

26new Class[] { Class.forName(interfaceName) },

27new InvocationHandler() {

28

29 @Override

30public 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());

35return result;

36 }

37

38 });

39 logger.debug("afterPropertiesSet......");

40 }

41

42 @Override

43public Object getObject() throws Exception {

44 logger.debug("getObject......");

45return proxyObj;

46 }

47

48 @Override

49public Class<?> getObjectType() {

50return proxyObj == null ? Object.class : proxyObj.getClass();

51 }

52

53 @Override

54publicboolean isSingleton() {

55returntrue;

56 }

57

58public String getInterfaceName() {

59return interfaceName;

60 }

61

62publicvoid setInterfaceName(String interfaceName) {

63this.interfaceName = interfaceName;

64 }

65

66public Object getTarget() {

67return target;

68 }

69

70publicvoid setTarget(Object target) {

71this.target = target;

72 }

73

74public Object getProxyObj() {

75return proxyObj;

76 }

77

78publicvoid setProxyObj(Object proxyObj) {

79this.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 })

3publicclass MyFactoryBeanTest {

4

5 @Autowired

6private 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

15publicvoid testFactoryBean() {

16 HelloWorldService helloWorldService = (HelloWorldService) context.getBean("fbHelloWorldService");

17 helloWorldService.getBeanName();

18 helloWorldService.sayHello();

19 }

20 }

 

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

以上是 SpringBeanFactory与FactoryBean的区别及其各自的详细介绍于用法 的全部内容, 来源链接: utcz.com/z/517815.html

回到顶部