BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的B5 W Z a k S L ; ~eanFactory无法支持spring的许多插件,如AOP功能、Web应用等。
Applicati6 e i E e N :onContext接口,它由BeanFactor| D 2 y S ny接口派生而来。4 d OApplicationContext包含BeanFactory的所有功f - N Z N 能,通常建C * b l议比BeanFactory优先。
BeanFactory= $ i p和FactoW r D k _ ; 4 O ~ryBean的区别
BeanFactory是接口,提供了OC容器最基本的形式,给具体的IOC容器的实现提供了规范,
FactoryBean也是接口,为IOC容器中Bean的- o Y m Q e实现提供了更加灵活的方式,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()方法中灵活配置。其实在Spring源码中e 7 x / M L w -有很多FactoryBean的实现类.
区别:BeanFactory是个Fb e 1 4 ? E @actory,也就是IOC容器或对象工厂,FactoryBean是个# , # &Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。
但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似
1、BeanFactory
BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中K c z n P的对象及建立这些对象间的依赖。
Beanv Z p | g 5 { ` gFactory只是个接口,并不是IOC容器的? X R Q具体实现,但是Spring容器给出了很Y N f e $ o H ] 9多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,: _ |其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用。
都是附加了某种功能的实现。它为其他具体的IOC容器提供了最基本的~ 3 O j S 7 &规范,例如DefaultListableBeanFactory,XmlBeanFactory,ApplicationConth G b a y @ ! 4ext 等具体的容器都是实现了BeaJ t ! & 7nFactory,再在其基础之上附加了其他的功能。
BeanFactory和ApplicationConH 0 . a $ Otext就是spring框架的两个IOC容器,现_ m ( V n ( ] 1在一般使用ApplicationnContext,其不但包含了BeanF} _ A ^ & J - . Vactory的作用,同时还进行更多的n w k l c a扩展。
BeanFacotry是spring中比较原h ? U始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。
原始的BeanFactory无法支持spring的许多插件,如AOP功^ O F能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来,
ApplicationContext包含BeanFa5 : % ? _ & -ctory的所有功能,通常建议比BeanFactory优先
ApplicationContext以一种更向面向框架的方式工作以及对上下文进行s t ? r X 1 T +分层; : 7 q v W y和实现继承,ApplicationContext包还提供了以下的功能:
- MessageSource, 提供国际化的消息访问
- 资源访问,如URL和文件
- 事件传播
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层;
在不使用spring框架之前,我们的service层中要使用dao层的对象,不得不在service层中new一个对象。存在的问题:层与层之间的依赖。
servh W M @ : ~ 8ice层要用dao层对象需要配置到xml配置文件中,至于对象是怎么创建的,关系是怎么组合的都交给了sprB j H @ h eing框架去实现。
方式1、
Resource resource&^ s ) y ; F @ U $nbsp;= new FileSystemResou, t Y d B V z ~ qrce(\"beans.xml\");
BeanFactory  4 ] C t qp;factory = new XmlBeanFactory(reso[ & ) 9 T aurce);
方式2、
ClassPathResource resource =&nbT Q ( p q 0sp;new ClassPathResource(\"beans.xml[ i 2 G\");
BeanFactory factor9 U F G b , yy = new XmlBeanFactory(resource);
方式3、
ApplicationContext c K k 3;cI yontext = new ClassPathXmlApplicationContext(new StriD y R H g G c 6ng[] {~ a X p # y q 2\"appX ( x A 9 w h ]licationContext.xmq ( ? } nl\", \"applicationConteo A 8xt-part2.xml\"});
BeanFactory factory = ` 2 u & i H 9;(BeanFactory) context;
基本就是这些了,接着使用getBean(String be; ( { K n Z a - Fas w ` ~ X _nName)方法就可以取得bean的实例;BeanFactory提供的方法及其简单,仅提供了六种方法供客户调用:
- boolean containsBean(String beanName) 判z _ 4 * 8 W j断工厂中是否包含给定名称的bk @ = ]ean定义,若有则返回true
- Object getBean(StrinG l y R z E ( , ]g) 返回给定名称注册{ W 的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实{ K * C例,如果没有找到指定bean,该方法可能会抛出异常
- Object getBean(String, Class= $ 4 C )) 返回以给定名称注册d ~ ~ U ~ 5 p 6 X的bean实例,并转换为给定class类型
- Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeV & ? D d k , K %anDeE w y pfinitionException异常
- boolean isSingle1 f r uton(String) 判断给定名称的bean定义是否为单例模式
- String[] getAliases(String nD w q w Dame) 返回给定G N P q ? T cbean名称的所有别名
packA - X = G Mage org.springframework.beans.factory;&n5 . $ ) ( p Ebsp; 3 ] % # U t s;
import org.springframework.beans.BeansExcept5 T : 2 ~ion;
public interface BeanFactory {
String FACTORY_BEt C * BAN_PREFIX K l m [ D P 4= \"&\";
&nbsr } sp; Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T>A |; T getBean(Class<T&Z 5 Tgt; requiredType) throws BeansEx` @ # F $ [ Gcepti. ? %onT | s;
Object getBean(String name, Object... args: B 5 @ C 5 } T G) throws BeansException; 1 @ * #
boolean containsBean(String name);
boolean isSingleton(String name)W $ ] ; J r J throws NoSuchBeanDefinitionException;
? q H 4 Q + s 8 boolean isPrototype(Strin. ` 4 X & m J Vg name) throwsU ) c j s NoSuchBeanDefinitionException;
&nbsW x , [ k i ep; boolean isTz W J g : [ypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
, W u ! T f @ String[] gee I 5 AtAliases(String I P L k w;name);
}
2、Factory$ p Z 5Bean
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实n y K s 8 @例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按d 9 0 Z照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。Fa) f F * $ CctoryBeaD 9 2 m | nn接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它b ] g T ;们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBe@ c f 9 R D H ; 9an<T>的形式
以Bean结5 ^ x * G尾,表示它是一个Bean,h 3 0不同于普通Bean的是:它是实现了FactoryBean<T>接口的Bean,根据该Bean的In U I $ g !D从BeanF) c & ! ~ [actory中获取的实际上是FactoryBean的getObject()返回的z @ u L B对象,而不是FactoryBean本身,如果要获取FactoryBeK k N gan对象,请在id前面加一个&符号来获取。
例如自己实现一个FactoryBean,功能:用来代理一个对象,对该对象的所有方法做一个拦截,在调用前后都输出一行LOG,模仿ProxyFactoryBean的功能。
/**
* my&nbs6 p W 2 D d [ u }p;factory bean<p>
* 代理一个类,拦截该类的所有方法,在方法的调用前后进行日志的输出
* @authS J # : G c ior daniel.zhao
*
x ^ 2 t U*/
publicY s ) e T J class MyFactoryBean implements Factn G / - + w U H ooryB . * x | `ean<Object>, InitializingBean,&2 ~ c % E Knbsp;DisposableBean {
&- } =nbsp; private static final Logger logger = LoggerFactory= G v # & U ).getLogger(MyFactoryBean.class);
private String interfaceName;
private Object target;&nbe ] { hsp; &nbd v r _ p Asp;
&nbt A ; [ - W ^sp; private&n8 V o : F G m + ]bsp;Obj6 G `ect proxyObj; &_ = = $ s lnbsp;
@Override
public void destroy() throws e b ^ Y;Exception {
logger.debug(\"destroy......\");
}
&n p P Q 6 a =bsp;@Override
public void afterPropertiesSet() throws Exception {
&i { { ; P B h Knbsp; proxyObj = Proxy.newProxyInstance(
&n% Q ~ 2bsp;  % G J A . l I; this.getClass().getClassLoader(), { X S n *;Y Y 1 i [ o w 1 U
&* s F Snbsp; new Class[] { Class.fm F j ^ @ R NorName(interfaceName) },
&nbs # H N F Fp; &nb_ . l C B N b dsp;new InvocationHandler 3 P ` $ 4r() { &nbs% G ] r tp;
$ u B E G @Override
&nbS g 2 & j ^ R Esp;&nb/ ! W $ + M ( xsp;&nbG } / h T X 5sp; &nb% b Y U !sp;public Object invoke(Object proxy,&nbsf $ Lp;I o D u * g H %Method method,&a G ` r 5 snbsp;Object[] args) throws Throwa8 9 rble {
&nbss 6 n N c 3p; &nbsX 2 c )p; &nbsa @ L Xp; logger.debug(\"invoke method......\" + method.getName());
w ) d . ) n E 2 / X ! &n1 n ! @bsp;~ S ! Z n   @ _ _ : O |p; logger.debug(\"invj 7 H moke method before..5 3 2 % , u.V [ = z v..z B 6 x ( T l [.\" + System.currentTimeMillis());
&nX & z Sbsp; &nbsl & _ d I Dp;Objectg b M } p . g z result = 4 ` L O;method.invoke(target, args);
s - l H _ F &n* a F . & ?bso a % 1 l A P 7p; logger: I 4 {.debug(\"invoke method after......\" + System.currentTimeMillis());
&nbw A F ! o V *sp; &k Y q Pnbsp;retu* r u xrn result; P i . m y 5 @ R I N : [ }&8 + d { ! +nbsp; &n- h k B bsp; &n5 V v 3 9 Cbsp;
&[ C . `nbsp% B U _ y 3 J +;});
&1 z & M p z Onbsp; &nbsb q F C o 3 { Mp; loggV : L jer.debug(\"ao E N yfterPropertiesSet......\");
&nbJ 5 ^ s A M $ P 5sp; }
@Ol n g D . ` 5 xverride
&nY S f [ / 0 V ebsp; public Object getObject() throws Exception {
B ~ s 0 { O % 9 logger.debug(F % N o (\"getObject......\");
return proxyObj;
}
&nbsG # n U v ] : N Up; @Overrio d M & ( Pde
 h V $ a i t S 2; publi~ X / H C Cc p h A g : R X ~;Class&( v M O ^ . ] V ilt;I ( 8 o } ; ~?&4 V |gg c ^ ? /t; getObjectType() {
 G | a; return proxyObj == null ? Object.class : proxyObj.getClass()U . # i;
&nb( # { S F [ / zsp; }
&n2 ` n 2 - , d ~bsp; @Override
public boolean isSingleton() {
&nM 6 =bsp;&nbs2 Q E Ip; &n: : ^ r 7bsp; return true;
&d F ! | S F j Jnbsp;&ni = q ) v , x fbsp; }
public String getInterfaB ] 4 V H $ |ceName() {
retH ` 8 3 U ? !urn interfaceName;
}
public&n? ] mbsp;void 9 ? O v;setInterfaceName(String interfaceName) {
&nbs6 j u V ap; this.interfaceName] 3 5 K 9 0 + d = interfaceName;
&nbw O 7sp; }
public Object getTarget()&z R b { I Y M =nbsp;{
return target;
}
public void setTarget(Object target) , k s t F U;{
 P N = , -; thisL z @ U O e 0.target = tarD 7 g R Cget;
}
public Object getProxyObj() {
&n$ 0 x p r 9 Zbsp; return proxyObD =j;
}
&nbs^ 4 5 Y p; publl _ | y l jic&k ynbsp;void setProxyObj(Object&n- z I w +bsp;proxyObj)&nI e L B A W 9 pbsp;{
this.proxyObj = proxyObj;
}
}
XML-Bean配置如下
<bean id=\"f/ d B l Q H 3 nbHelloWorldService\" class=\"com.ebao.xxx.MyFactoryBean\">
<property name=\"interfaceName\" value=\"com.ebao.xxx.HelloWorldS~ 0 j q @erv? e 3 8 X K #ice\" />
<property name=\"target\" ref=\"helloWorldService\"&b _nbS 5 . ? Q rsp;/>
</bean>
Junit Test class
@RunWith(JUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyFactoryBeanConfig.clI P S 0 ] $ass })
public class MyFactoryBeanTest {
F 2 Z @Autowired
B b ? m cprivate ApplicationContext W H a;context;
/**
* 测试验证FactoryBean原理,代理一个servcie在调用其方法的前后,打印日志亦可作其他处理
* 从Applit e ` 6cationContext中获取自定义的FactoryB1 = y 8 N ean
&nbC B ~ ; @ g 1 Msp; * context.getBean(String&nbsk ; #p;beanName) ---> 最终获取到R u m ] g w s的Object是FactoryBean% H H 5 I / T l.getObejct(),
* 使用Proxy.n2 Z 5 ; , o .ewInstance生成service的代理类
&no @ Z q a F = $ Hbsp; */
- t n @Test
public&nbC S _ + 2 K K ~sp;void testFactoryBean() {
HelloWorldService&n 4 o ) [bsp;helloWorldService R n | Y;= (HelloWorldService) context.getBean(\"fbHelloWorldService\V Z j V ; m ; {");
helloWorldService.getBeanNamv + `e();
&nbb 7 nsp; j y Q | x 1 d | helloWorldService.sayHello();
&nb^ R P n V & 9sp; }
}
FactoryBeanN + i y )是一个接口,当在IOC容器中的Bean实现了FactoryBean后,通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObF N H / m $ n 5ject()方法返回的对象。要想获取FactoryBean的实现4 i j { ) ) l类,; v v ~ 9 : s (就要getBean(&BeanName),在BeanName之前加上&。% h S o h l
Java代码
package org.springframework.beans.factory; &m u cnbsp;
public i G w f E s );interface FactoryBean<T> {
 } / h r h *; T getObject()&nbE e : O ` K a Psp;throws Exception2 ] b M;
Class<?> getObjectType();
boolean isSingleton();
}
在该接口中还定义了以下3个方法:
- TgetObject():返回S Y R t g d由FactoryBean创建6 d q R x T 6 r的Bean实例,如果isSingleton(O E 0 i p a S w)返回true,则该实例会放到Spring容器中单实例缓存池中;* V _ D K X E 9 M
- booleanisSingleton():返回由FactoryBean创建的Bean实例的作用域是sinA ` Bglx y H S 8 t ? *et2 ( X l 4 ~on还是prototype;
- Class<T>getObjectType():返回FactoryBeaE ~ - / % z & V Cn创建的Bean类型。
当配置文件中<bean>的class4 v % c属性配置的实现类是FactoryBean时K ^ ] V j 7,通过getBean()方法返回的不是Fay & W ` NctoryBean本身,而是FactoryBean#getObj~ j B = { * ^ect()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。
例:如果使用传统方式配置下面G : S Z % 1 b lCar的<bean>时,Car的每个属性分别对应一个<property>元素标签。
package com.baoR = t . - S I ~ 5baotao.factorybean;
&nb V f 8sp; public class Car {
&nZ g | Y / 7 { w Fbsp; private int maxSpeed ;
private&n& [ d v ) i . ?bsp; String ! G : 9 G Z l L;brand ;
&S ! M F | o L +nbsp;&nbsl T b J Hp; private double price ;
 X - 5 w;  t w R 0 % 3 T j l; &nB 5 & / Obsp; public&nd 5 % 6 - bbsp;&u ; D /nbsp; int getMaxSpeed () {
&nb~ ] B rsp; &nbsC e W e # U U yp; return this .&nbc s 0 ~sp;maxSpeed ;
&nbs} ` * s ; R ? L Vp; }
public void g : - 8 S setMaxSpeed ( int maxSpeed ) {
D X q w v f b K # ; d r ` ` 8 $ 2 q : V this . H & 1 E 1 H : [;maxSpeed &q D y { F $ q / Vnbsp;= maxSpeed;
 u 9 W n _ s; }
&nc - absp; &nbs& O = Ap; &nbsn ) a p T ` 8p; public String getBrand () &nbsm Y B , a | P 6p; % C R ? L j / @ Q{
&nbse O #p; &k % c V y g : i ;nb0 W J T j 2 : z !sp; return this . brM m b ~ band ;
}
publi4 M B / T 4 ~ qc  m f s ^ W 9; void sz R betBrand ( String brand ) {&h F ^ f 1 t U k Pnbsp;
 k # # 2 = @ } Y; this . brand &X 1 q q R Lnbsp;= brand;
&h b _ S Cnbsp; &nl A + i } V 7bsp; }&l V Mnbsp;
&nbsZ + t n o q G Sp; v 1 X y h ); publi] a [ o yc double&nbsd Z k ; s ; 6 g vpy l T X D @; getPrice ({ 5 e W k j) {
= m V y Z ] X , p return this .&P n V X F Rnbsp;price ;
}
&nS g K F ~ ) 4 nbsp; &n; R i 1 & N Lbsp; &j B R Unbsp;public &nbs_ # T W I Z f *p;void P % asetPrice&nH . j 6bsp;( double price ) &nby q t e Z 1 Psp;{
&nv 4 Absp; / T n $ = - &3 8 =nbsl I C a u vp; this&m J e r : knbsp;. price = C d 5;price;
&s Q ;nbsp; }
}
如果用FactoryBeaq J = A & 2 en的方式实现就灵活点,下例通过逗号分割符的方式一次性的为Car的所有属性指定配置值:
package com.baobaotao.n b H Vfactorybean;
import &nbsm d 9 5p;org.s | @springframework.beans.factory.FactoryBean;
public class CarFactoryBean i$ _ ~ 9 ` { .mplements FactoryBean<Car>  # p h e ^ , $ R;{
g m & e &nbD k 3 D b y .sp; prX # 1 = P W Jivate&nh S u 0 F j t ( gbsp; S7 Y Z _ d { 5tring carInfo ; &nbF R Q } D 2 p Gsp;
 g ] o }; public Car getObjecI J & B v w k it () throws Exception {
&g q O , 7 q P /nbsp; &z ^ 8nbsp;Car car = new &n. ~ 1 ^ )bsp;Car () ;&nbV 8 j ; asp;
&nM ! )bsp; String [] infos = carInfo&n* h . N [ { | t vbsp;.split ( : o 4 r\",\" ) ;
&F 3 K p 2 : nbsV 7 a 8 pp; car.se@ @ h E q =tBrand ( infos [ 0 ]) ;
&S ^ F 8 - x &m ` K r w x (nbsp; car.setMaxSpeed ( Integer. valueOf ( infosb 6 C y B c x&nbg n | Csp;[ 1 ])) ;
&n@ L k d P qbsp;car.setPrice ( Double. valueOf ( infos [ 2&nbsA O ^ Pp;])) ; : o e O 1 t H };
&v C w 5 snbsp; return car;&nbF / v R X A m N $sp;
&o e F 2 G (nbsp;}
&nbs8 u @ T J n -p; &na # G g e d ;bsp;Q q qpublic Class<Car> getObjectType () j C J; &nb} A u . & F +sp;{
return M b 9 Z DCar. class ;
}
public &nb$ E f o ! [sp;boG ? {olean &nbsj Q ) ; G I Gp;. e a | +isSingleton () {
return faS A B x 6 _ r , ;lse ;
}
public String getCarInfo () K s I W % Z = {N X E _ Y D } c U
&nbsB o B 0 q T Yp; return&no ( Z ) } F : )bsp; this . carg u W OInfo ;
}
// 接受逗号0 i x U 7 j分割符设置属性信息
public  F * Z i K [ % e;void setCarInfo ( String carInfo ) {
&nby a } t Usp; this . carInfo = carInfo;
F a ) w M } &v x onbsp;
}
有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置CarBean了:
<beaE @ { o ?n d=\"car\"class=\"com.baobaotao.facto5 ^ U Q vrybean.CarFactoryBean\"
P:carInfo=\"法拉利,400,2000000\"/>
当调用getBean(\"car\")时,Spring通t 9 m L n 1 S过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。如果希望获取CarFactoryBean的实例,则需要在使用getBean(beanName)方法时在beanName前显示的加上\"&\"前缀:如getBean(\"&car\");
下面是一个应用FactoryBean的例子
<beans xE X K # p c & omlns=\"http://www.springframew- ` T C N 8oi P H ` c ,rk.org/schema/beans\"
V ] . X B ! ( F xmlns:xsi=\"htQ a ztp://www.w3.org/2001/XMLSchema-iH ^ B L f P nnstance\"
&nbH l * d h W asp; &n[ N { 3 Ibsp; xmlns:context=\"http://www.springframework.org/schema/cM v e k xontext\"
&nbsa V Vp; B D ( ! a G xmlns:aop=\"http://www.springfra` c : ~ A | ^mework.org/schema/aop\"
 b 4 s; &nbs- # = r xp; &# g g I , 9 1nbsp;&nbL 5 H b ! ; # t ispI { * u; &7 S g 1 % 7 6nbsp;&nbs z + Ap;xmlns:tx=\"http://wwQ Y + V | - ow.springframeworkw t ^ # J !.org/schema/tx\"
&nbK | ? Asp; &nb* Z ) B usp;C w s i O w W { fxsi:schemaLo1 ) 7 M & E ^ Mcation=\"http://www.springframework.org/schema/beans n O 0 f L S V Y
 ! N K; &nbs5 & F - t V h q #p;&n) v 2 ~ q ? | 3 dbsp; &nbs= E J Xp; http://www.springframework.org/schema/beans/spring-beans-3.0.xsd&@ F U ^ - @ m rnbsp;
k Z f c f ~ e I s k w I http://www.springf# S z Z u d I dramework.org/schema/context
 5 S n;  q ? A;  = d : E u N; http://www.springframework.org/schema/context/spring-context-3.0.xsd&nbx D Xsp;
&S = | h : lnbsp; &N J F o T u @ [ `nbsp;  3 X ! );&n] b V : r R o wbsp; http:} ] Z @ W//www.springframe~ 4 5 g S 9 x TwA 8 D m Sork.org/schema/aop
&nbs+ q 0 !p; 8 h b t http://www.sprU b bingframework.org/schema/aop ( j f Up/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
&n+ M 8 Xbsp;  D E @ &; &nu u ~ 9 N gbsp; http://wwwT q x R H - M } $.springfram* Z ~ / J V p , rework.org/schema/tx/spring-tx] = b o 8 ; { T-3.0.xsd\">
<bean id=\"student\" class=\"com.spring.bean.Student\"> &nI 1 O @ 3bsp;
 P 7 I {;<property name=\c _ + I * q , m H"name\" value=\"zhangsan\" />
</bean> &n6 & _bsp;@ D 2 O F b
<bean id=\c r X ; V J b _ 7"school! Y 6 _ G B ] i &\" class=\"com.spring.bean.School\">
</bean>: a
<bean id= ! U & W F ^ b=\"factory3 v a # C @ Y 4 .BeanPo= 0 P k 4jo\" class=n 1 T\"t K ^ y ccom.spri5 1 % Mng.bean.FactoryBeanPojo\">
<property name=\"type\" value=\"studend o 0 v a e Vt\" />
&nbsr [ F P Y /p;</bean>
</beans>
FactoryBeL F wan的V A 5 / l实现类
import org.springframeF * . 3 p O x ^ twork.beans.factory.FactoryBean;
/**e W d C K ; 7 B [ P g
*2 : T @aut1 B % } H 5hor 作者&6 y L Bnbsp;wangbiao
* @parameter m 6 * h E J F Q a;
* @return
*? b i t m */
p/ 6 l ^ y 5 l L zublic class&9 2 I 1 j +nbsp;FactoryBeanPojo implements FactoryBean{
private String type;&nbv # Bsp;
&nbsR i } ( i / : : fp;@Override
f H T 3 C u L y n L t i ]public Object getObject() throws Exception&nbsc 2 Bp;{&~ O $nbsp;
if(\"student\".equals(type)){
return new Student();  ) K { !;
&- Z ^ 0 mnbsp; &nb2 } 2 8sp;  e o c E z , 1 u;}else{
&_ : a 8 2 L ) S bnbsp;return nw Z } c 3 W Few&nbsa ? ! ` M x ep;, C kSchool();
}
}
@Override O ) : p B { J
&nU x 9 . N 2 2bsp;public Class getObjectType() { f d $; B n 2;
 S P L G g ,; return School.class;
}
@Over^ p f ) 0 J Y 0ride &n2 + F * cbsp;
public boolean isSingleton() {
&nbi j - j j y Dspi k h i K ) Z * e; return true;
}
public G ; = i Y U C /;String getType() {
- G s . l R y ]return type;
}
public void setType(String type) { a 4 ~ 9 ,;
this.type = type;
}
}
普通的bean
/**
* @author 作者 wangbiao
* @parameter
* @return
*/
public class School 1 H k a z L{
private S3 3 A r m Ctring schoolName;
privatb 6 f | 5 Xe S_ , l P W 1 Ztring&nbu 8 # V X M R rsp;addres{ 8 z ? ^s;
pra m $ %ivat8 n U r ye int studentNumber; f 3 R u . 0 6;
$ = o h public String getSchoolName() {
&nbe M 8sp; return schoolName;
}
& V d x . l xnbsp;public void setSchoolName(String sJ h ^ n 7 ZchooB 8 L { % Z f s FlName) {
[ x c p m L &nbM + Wsp; this.schoolNa; i h ,me&n z 6 # V B W pnbsp;= schoolName;
@ ^ 0 R B&P 0 | . E L O 9nbsp;}&R z X 5 U 3 .nbsp;
public String getAddres| S - P o Q es() {
return address;
&- @ ; w q w bnbsp; }
&nbu J p $ }sp; public void setAddress(Stb M s k e | 0 Kring address) {
this.address = address;
L / L S ` u @}
public int getStudo R M + o ; ( 7en6 U l @tNumber() {&nbI 6 - psp;
return studentNumber;  h e ^ s;
&nD V [bsp; : o b 1 E r + 0 X; }
public&n) n n F ; % `bsp;void setStK g $ 7 ~ 0 cudentNumber(int studentNumber) {
&! V ( q Hnbsp; this.studentNumber =J y 4 0 studentNumber;
&n| 8 C bbsp; }&nb F R ( [ d m u 7sp;
&nbsJ 9 6 r lp; @Override
public String toString() {
&Q f - l ` f % 0 snbsp; &nbD N K s 0 rsp; return \"Schoo| [ ! R i Hl [schoolName=\" l D - 9;+ schoolName + \", address=\" + address
&nbI _ @ I 9 = 0sp; &n2 u Y ` R $ 9 7 obsp; + \6 U & h T k", studC } { | /ente x I e fNumber=\" + studentNumber + \"]\"; &nb9 , . @ } f L 3 nsp;
&W K , 5 ? z f Inbsp; &~ g 6 i $nbsp; }~ S @ % 0 W * ` h
}
测试类f I 5 w
import o| i ` y ` 0 Y = -rg.springframework.context.support.ClassPathXmlApplicationContext;&nj 7 R L C V l ebsp;
imS n m 4 Aport com.spring.bean.FactoryBeanPojo;
/**&nb: k 2 dsp;
* @author &p u e 7 #nbsp;作者 wangbiao
* @p_ 8 J 9 ^ - 9 rarameter
* @return
*/
public class FactoryBeanTest {
&nb; & # A J z ^ M isp;&n= 5 & 6 h ^ d / Dbsp( % x } # n D (;&nbi c [ _sp;public static void 5 _ U r ) # bmain(String[] args){ &+ [ 3 ( % cnbsp;
String url = \"com/spring/config/BeanConfig.x2 x f lml\";
&nb- B L A esp;ClassPa, B @ j [ 7 [thXmlApplicationContext cpxa = new ClassPathXmlApplicationContext(url); = I p ^ m
2 p U # p X Q ! &nbsS S dp; v p + 6 = l ] [;&nbsg U { 1 1p; Object school= ( e n (cpxa.getBean(\. 2 u ( : V 5"factoryBeanPojo\");
Fau z 6 I EctoryBeanPojo factor9 [ ; ^ = e @ F ,yBeanPojo= (FactoryBeanPojo) cpxa.getBean(\"&factorY C 0 + y w F A xyBeanPojo\");
System.out.println(school.getClE 3 r ^ bass().getName());
 u W H L r W;&nb/ 0 b f ) Asp;  ] o e i r 0 * n $; Q | 7 5System.out.println(factoryBeanPojo.getClass().getName());
}
}
输出的结果:
十一月 16, { % = k v # Z K&5 + Z l 5nbsp;k v Y2016 10:28:24 上午 org.spriL R jngframe I r e K & O L cwork.context.support.AbstractApplicationContt & * 6 f u s H ]ext prepareRefresh
INFO: Refry ~ P 6 I 8 !eshing org.springframework.context.support.ClassPathXmlAp` I V i 6 1 E (pl. P S 5 r m S DicationContext@1e8eec C U 5c0: startup ^ . L S;date [Wed Nov 16 10:28:24 CST 2016]; root of context hierarchy
十一月 16, 2016 10:28:24 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class$ l ? path / ) 8 ^ $ o;resource [com/spring/co@ 6 Infig/Bk v j 0 Z r w *eanConfig.xml]
十一月&n; ( O h / = w mbsp;16, 2016 . @ 1 n10:2S Z X _ Y } #8:24 上午 or^ n ag.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO:&nbt 0 y ~sp;Pre-instantiating singletons in&nbs9 Z v t b h H Qp;org.springframework.beans.factory.sup# - Z 6port.DefaultListableBeanFactory@35b793ee: defining beans [student,school,factoryBeanPojo]; root of factory hierarchy
coh V M : : {m.spring.bean.Student
com.spring.bean.FactoryBeanPojo
从结果上可以看到当从IOC容器中获取Fa^ Q g R : CctoryBeanPojo对象的时候,用getBean(String BeanName)获取的确是Student对象,可以看到在FactoryBeanPojo中的type属性设N w ; = c * `置为student的时候,会在getObJ G ] 0 Q 1 b Aject()方法中返回Student对象。
所以说从IOC容器获取实现了FactoryBean的实现类时,返回的却是实现类中的getObject& ` / # `方法返回的$ O u ) G 5 V v对象,要想获取FactoryBean的实现类,得在M ] ^getBean(String BeanName)中的BeanName之前加上&,写成getBean(String &BeanNaF 0 e C P 5 ,me)。
Java知音,专注于Java实用文章推送,不容错过!
来源:cnblogs.com/aspirant/p/9082858.h9 . gtml