Spring FactoryBean机制介绍

前沿:

在说spring之前,先提一下spring的基本原理,依赖注入,控制反转。我们在配置spring的时候有两种bean可以配置,

一种是普通bean:配置的class就是生成的bean的真正对象。

一种是工厂Bean,即FactoryBean:配置class不是生成bean的真正对象。

他们都被spring容器管理,工厂Bean其返回的对象不是指定类的一个实例,是该FactoryBean的getObject方法所返回的对象。

普通人可能只知道一种,在Spring内部,有很多地方用到FactoryBean实现功能,

应用:它们在很多应用如(Spring的AOP、ORM、事务管理)及与其它第三框架(ehCache)集成时都有体现,

实现:

1. FactoryBean接口

 1 package org.springframework.beans.factory;
 2 
 3 public interface FactoryBean<T> {
 4 
 5     T getObject() throws Exception;
 6     
 7     Class<?> getObjectType();
 8  
 9     boolean isSingleton();
10 
11 }    

其中是java泛型机制实现,即T表示要生成的对象。也可以不使用,推荐使用。
getObject()方法返回欲生成对象。getObjectType()欲返回对象类型,isSingleton()获得对象的机制(singleton|prototype|request|session).

2. 例子:mybatis和spring集成实例

 1 package com.debug.factory;
 2 
 3 import java.io.InputStream;
 4 
 5 import org.apache.ibatis.io.Resources;
 6 import org.apache.ibatis.session.SqlSessionFactory;
 7 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
 8 import org.springframework.beans.factory.FactoryBean;
 9 
10 public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory> {
11     SqlSessionFactory sessionFactory;
12 
13     @Override
14     public SqlSessionFactory getObject() throws Exception {
15         System.out.println("getObject");
16         String resource = "mybatis-config1.xml";
17         InputStream in = Resources.getResourceAsStream(resource);
18         sessionFactory = new SqlSessionFactoryBuilder().build(in);
19         return sessionFactory;
20     }
21 
22     @Override
23     public Class<?> getObjectType() {
24         // TODO Auto-generated method stub
25         System.out.println("getObjectType");
26         return SqlSessionFactory.class;
27     }
28 
29     @Override
30     public boolean isSingleton() {
31         System.out.println("isSingleton");
32         return true;
33     }
34 }

application.xml配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xmlns:context="http://www.springframework.org/schema/context"
 6     xmlns:tx="http://www.springframework.org/schema/tx"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
 9         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
10         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
11 
12     <bean id="mysqlsessionfactory" class="com.debug.factory.SqlSessionFactoryBean" scope="prototype">
13     
14     </bean>
15 </beans>

调用测试代码

1 ApplicationContext app = new ClassPathXmlApplicationContext("application.xml");
2 {
3     SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) app.getBean("mysqlsessionfactory");
4     System.out.println(sqlSessionFactory);
5 }
6 {
7     SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) app.getBean("mysqlsessionfactory");
8     System.out.println(sqlSessionFactory);
9 }

生成:

1 isSingleton
2 getObjectType
3 isSingleton
4 getObject
5 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@8458f04
6 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@8458f04

说明,容器通过getBean方法返回的不是SqlSessionFactory本身,而是FactoryBean实现类中getObject()方法返回的对象。 

上面代码是自己集成的mybatis如果用官方的包可以使用spring mybatis项目提供的代码mybatis-spring-1.2.0.tar.gz中的org.mybatis.spring.SqlSessionFactoryBean。

spring配置如下:

1 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
2     <property name="dataSource" ref="dataSource" />
3     <property name="configLocation" value="classpath:mybatis-config.xml" />
4 </bean>

3. FactoryBean的扩展应用之Spring集成 ehcache

 1 <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">    
 2     <property name="configLocation">    
 3         <value>classpath:ehcache.xml</value>    
 4     </property>    
 5 </bean>
 6 <bean id="levelOneCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">    
 7     <property name="cacheManager">    
 8         <ref local="cacheManager" />    
 9     </property>    
10     <property name="cacheName">    
11         <value>levelOneCache</value>    
12     </property>    
13 </bean> 

调用代码

 1 public class MainTest {  
 2     public static void main(String[] args) {  
 3         Resource res = new ClassPathResource("bean.xml");  
 4         BeanFactory factory = new XmlBeanFactory(res);  
 5         //取到CacheManager类的实例   
 6         CacheManager cacheManager = (CacheManager) factory .getBean("cacheManager");  
 7         //取到Cache类的实例   
 8         Cache levelOneCache = cacheManager.getCache("levelOneCache");  
 9     }  
10 }  

更过详细设置参考其他详细资料!

原文地址:https://www.cnblogs.com/hnxubin/p/4289568.html