Spring中的BeanFactory與FactoryBean區(qū)別詳解
概述
- BeanFactory是一個(gè)接口,它是spring中的一個(gè)工廠,能夠生產(chǎn)bean,獲取bean,也就是IOC容器或?qū)ο蠊S。
- FactoryBean也是一個(gè)接口,實(shí)現(xiàn)了3個(gè)方法,通過重寫其中的getObject()方法自定義生成bean邏輯創(chuàng)建一個(gè)新的bean,為IOC容器中Bean的實(shí)現(xiàn)提供了更加靈活的方式,F(xiàn)actoryBean在IOC容器的基礎(chǔ)上給Bean的實(shí)現(xiàn)加上了一個(gè)簡單工廠模式和裝飾模式。
- 不止Spring中,包括mybatis和HIibernate框架等大量地方用到了FactoryBean,可見其設(shè)計(jì)思想的重要性。
BeanFactory
BeanFactory是Spring里面最底層的一個(gè)接口,提供了最簡單的容器的功能,即實(shí)例化、配置和管理 Bean。
Spring中實(shí)例化容器的幾種方式:
1.類路徑下實(shí)例化容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(“classpath:spring.xml”); UserFactoryBean userFactoryBean = (UserFactoryBean) context.getBean(“userFactoryBean”);
2.系統(tǒng)目錄下實(shí)例化容器
ApplicationContext context = new FileSystemXmlApplicationContext(new String[]{“d:\beans.xml”}); UserFactoryBean userFactoryBean = (UserFactoryBean) context.getBean(“userFactoryBean”);
3.注解的方式實(shí)例化容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); UserFactoryBean userFactoryBean = (UserFactoryBean) context.getBean(“userFactoryBean”);
看一下BeanFactory的方法:
- boolean containsBean(String beanName) 判斷工廠中是否包含給定名稱的bean定義,若有則返回true
- Object getBean(String) 返回給定名稱注冊的bean實(shí)例。根據(jù)bean的配置情況,如果是singleton模式將返回一個(gè)共享實(shí)例,否則將返回一個(gè)新建的實(shí)例,如果沒有找到指定bean,該方法可能會(huì)拋出異常
- Object getBean(String, Class) 返回以給定名稱注冊的bean實(shí)例,并轉(zhuǎn)換為給定class類型
- Class getType(String name) 返回給定名稱的bean的Class,如果沒有找到指定的bean實(shí)例,則排除NoSuchBeanDefinitionException異常
- boolean isSingleton(String) 判斷給定名稱的bean定義是否為單例模式
- String[] getAliases(String name) 返回給定bean名稱的所有別名
FactoryBean
FactoryBean也是一個(gè)接口,它是一個(gè)bean,一個(gè)特殊的bean。實(shí)現(xiàn)了factorybean的bean,實(shí)現(xiàn)了如下3個(gè)方法:
- T getObject() throws Exception:實(shí)際返回的bean對象
- Class<?> getObjectType():獲取返回bean對象的類型
- boolean isSingleton():判斷是否是單例
- 通過重寫其中的getObject()方法自定義生成bean邏輯創(chuàng)建一個(gè)新的bean,為IOC容器中Bean的實(shí)現(xiàn)提供了更加靈活的方式
- 實(shí)現(xiàn)了factorybean的bean會(huì)在IOC容器中產(chǎn)生2個(gè)bean對象,一個(gè)是getObject()方法返回的bean對象,一個(gè)是實(shí)現(xiàn)了factorybean的bean的這個(gè)對象本身
- 通過@Component,@Service標(biāo)注了bean名字獲取的bean是getObject方法返回的bean;獲取實(shí)現(xiàn)了factorybean的bean則是通過,& + bean的名字獲取
下面我們看一個(gè)簡易demo:
1.編寫掃描配置類Appconfig,bean對象User,以及實(shí)現(xiàn)了factorybean的bean:UserFactoryBean,重寫getObject方法
@Configuration @ComponentScan("com.demo") @ImportResource("classpath:spring.xml") public class Appconfig { }
public class User { private String name; private int age; private String birthday; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getBirthday() { return birthday; } public void setBirthday(String birthday) { this.birthday = birthday; } }
@Component("userFactoryBean") public class UserFactoryBean implements FactoryBean { private String name; private int age; private String birthday; @Override public Object getObject() { User user = new User(); user.setName(name); user.setBirthday(birthday); user.setAge(age); return user; } @Override public Class<?> getObjectType() { return User.class; } @Override public boolean isSingleton() { return false; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setBirthday(String birthday) { this.birthday = birthday; } public String getName() { return name; } public int getAge() { return age; } public String getBirthday() { return birthday; }
2.編寫spring.xml配置文件,注入name,age,birthday屬性到userFactoryBean
<bean id="userFactoryBean" class="com.demo.UserFactoryBean"> <property name="name" value="xiaoming"></property> <property name="age" value="18"></property> <property name="birthday" value="1225"></property> </bean>
3.編寫test測試類
public class Test { @org.junit.Test public void test1(){ AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Appconfig.class); // 獲取UserFactoryBean對面本身 UserFactoryBean userFactoryBean = (UserFactoryBean) context.getBean("&userFactoryBean"); System.out.println("UserFactoryBean------姓名:"+userFactoryBean.getName()+";年齡:"+userFactoryBean.getAge()+";生日:"+userFactoryBean.getBirthday()); // 獲取實(shí)際返回的對象,通過getObject方法返回的對象 User user = (User) context.getBean("userFactoryBean"); System.out.println("User------姓名:"+user.getName()+";年齡:"+user.getAge()+";生日:"+user.getBirthday()); } }
看一下效果:
通過上述demo我們可以看到:
- 確實(shí)生成了2個(gè)對象。&userFactoryBean 獲取了UserFactoryBean對面本身;userFactoryBean 獲取了通過getObject方法返回的對象
- 這里demo里面spring.xml文件一個(gè)一個(gè)注入屬性到UserFactoryBean,若屬性特別多,UserFactoryBean內(nèi)部實(shí)現(xiàn)十分復(fù)雜,這時(shí)又該如何解決呢??getObjectd的用途之一就是在于此,我們可以把name,age,birthday寫了一個(gè)字符串在springx.xml注入到UserFactoryBean,然后在getObject方法中拆分字符串給user對象賦值。這里就達(dá)到了一個(gè)效果:當(dāng)一個(gè)類內(nèi)部特別復(fù)雜的時(shí)候,有n多屬性,n多依賴關(guān)系。想要對外提供一個(gè)簡單的方式可以配置起來,具體如何封裝通過getObjectd方法內(nèi)部自己實(shí)現(xiàn)。
總結(jié)
- BeanFactory是Spring里面最底層的一個(gè)接口,提供了最簡單的容器的功能,即實(shí)例化、配置和管理 Bean。
- FactoryBean也是一個(gè)接口,實(shí)現(xiàn)了3個(gè)方法,通過重寫其中的getObject()方法自定義生成bean邏輯創(chuàng)建一個(gè)新的bean,為IOC容器中Bean的實(shí)現(xiàn)提供了更加靈活的方式
- 實(shí)現(xiàn)了factorybean的bean會(huì)在IOC容器中產(chǎn)生2個(gè)bean對象,一個(gè)是getObject()方法返回的bean對象,一個(gè)是實(shí)現(xiàn)了factorybean的bean的這個(gè)對象本身。通過@Component,@Service標(biāo)注了bean名字獲取的bean是getObject方法返回的bean;獲取實(shí)現(xiàn)了factorybean的bean則是通過,& + bean的名字獲取
到此這篇關(guān)于Spring中的BeanFactory與FactoryBean區(qū)別詳解的文章就介紹到這了,更多相關(guān)BeanFactory與FactoryBean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Spring中BeanFactory與FactoryBean的區(qū)別解讀
- Spring中的FactoryBean與BeanFactory詳細(xì)解析
- Spring BeanFactory和FactoryBean有哪些區(qū)別
- Spring中BeanFactory?FactoryBean和ObjectFactory的三種的區(qū)別
- Spring?BeanFactory?與?FactoryBean?的區(qū)別詳情
- Spring BeanFactory和FactoryBean區(qū)別解析
- 簡單了解Spring中BeanFactory與FactoryBean的區(qū)別
- Spring中BeanFactory與FactoryBean接口的區(qū)別詳解
相關(guān)文章
Java 讀取、獲取配置文件.properties中的數(shù)據(jù)
這篇文章主要介紹了Java 讀取、獲取配置文件.properties中的數(shù)據(jù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-09-09詳解eclipse下創(chuàng)建第一個(gè)spring boot項(xiàng)目
本文詳細(xì)介紹了創(chuàng)建第一個(gè)基于eclipse(eclipse-jee-neon-3-win32-x86_64.zip)+spring boot創(chuàng)建的項(xiàng)目。2017-04-04java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)雙色球抽獎(jiǎng)算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解
這篇文章主要介紹了Java中三種零拷貝的實(shí)現(xiàn)示例以及對比詳解,本文主要是介紹幾種零拷貝的實(shí)現(xiàn)示例,以及與最傳統(tǒng)的做一個(gè)對比,看看在效率上到底有多大的提升,需要的朋友可以參考下2023-12-12