欧阳娜娜入职阿里,职级P8年薪百万!靠噱头还是靠实力?

一道阿里面试题:说说你了解的BeanFactory和FactoryBean的区别

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&nbsp 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 &nbsp @ _ _ : 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 C; 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 &nbsp;    &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

上一篇

女星年轻时有多美?本以为赵薇够好看了

下一篇

范丞丞为大家示范穿搭小公式,可甜可盐,小单品也能穿出男神范!

你也可能喜欢

  • 暂无相关文章!

发表评论

您的电子邮件地址不会被公开。 必填项已用 * 标注

提示:点击验证后方可评论!

插入图片
返回顶部