zoukankan      html  css  js  c++  java
  • Spring bean三种创建方式

      spring共提供了三种实例化bean的方式:构造器实例化(全类名,反射)、工厂方法(静态工厂实例化   动态工厂实例化)和FactoryBean ,下面一一详解:

     

    1、构造器实例化

    City.java

     1 package com.proc.bean;
     2 
     3 public class City {
     4 
     5     private String name;
     6     private String code;
     7     
     8     public City() {
     9     }
    10 
    11     public City(String name, String code) {
    12         this.name = name;
    13         this.code = code;
    14     }
    15 
    16     public String getName() {
    17         return name;
    18     }
    19 
    20     public void setName(String name) {
    21         this.name = name;
    22     }
    23 
    24     public String getCode() {
    25         return code;
    26     }
    27 
    28     public void setCode(String code) {
    29         this.code = code;
    30     }
    31 
    32     @Override
    33     public String toString() {
    34         return "City [name=" + name + ", code=" + code + "]";
    35     }
    36 }

    通过构造方式配置Bean

    1 <bean id="city" class="com.proc.bean.City">
    2     <constructor-arg value="北京"/>
    3     <constructor-arg value="BJ"/>
    4 </bean>

    测试代码

    1 ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
    2 City city=ctx.getBean("city", City.class);
    3 System.out.println(city);

    输出结果

    City [name=北京, code=BJ]

    2、静态工厂实例化

      先创建一个静态工厂StaticCityFactory

     1 package com.proc.bean;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 public class StaticCityFactory {
     7     
     8     private static Map<String, City> cities;
     9     
    10     static{
    11         cities=new HashMap<String, City>();
    12         cities.put("BJ", new City("北京", "BJ"));
    13         cities.put("SH", new City("上海", "SH"));
    14         cities.put("CD", new City("成都", "CD"));
    15         cities.put("SZ", new City("深圳", "SZ"));
    16     }
    17 
    18     public static City getCity(String code){
    19         return cities.get(code);
    20     }
    21 }

      配置bean

    1 <!-- 通过静态工厂实例化对象
    2     class:静态工厂类型
    3     factory-method:静态工厂静态方法名称
    4     constructor-arg:为静态工厂方法指定参数
    5  -->
    6 <bean id="city" class="com.proc.bean.StaticCityFactory" factory-method="getCity">
    7     <constructor-arg value="BJ"/>
    8 </bean>

    3、动态工厂实例化

      先创建一个实例化工厂

     1 package com.proc.bean;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 public class InstanceCityFactory {
     7     
     8     private Map<String, City> cities;
     9     {
    10         cities=new HashMap<String, City>();
    11         cities.put("BJ", new City("北京", "BJ"));
    12         cities.put("SH", new City("上海", "SH"));
    13         cities.put("CD", new City("成都", "CD"));
    14         cities.put("SZ", new City("深圳", "SZ"));
    15     }
    16     
    17     public City getCity(String code){
    18         return cities.get(code);
    19     }
    20 }

      配置

    1 <!-- 配置实例化工厂 -->
    2 <bean id="cityFacotry" class="com.proc.bean.InstanceCityFactory"/>
    3  
    4  <!-- 通过实例化工厂获取对象 -->
    5 <bean id="city" factory-bean="cityFacotry" factory-method="getCity">
    6     <constructor-arg value="SH"/> <!-- 配置参数 -->
    7 </bean>

    4、FactoryBean

      

       一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。

      FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:

    1 public interface FactoryBean<T> {  
    2     T getObject() throws Exception;  
    3     Class<?> getObjectType();  
    4     boolean isSingleton();  
    5 }

      在该接口中还定义了以下3 个方法:

        T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到Spring 容器中单实例缓存池中;

        boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;

        Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。

      当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了getBean() 方法。

      例:如果使用传统方式配置下面Car 的 <bean> 时, Car 的每个属性分别对应一个 <property> 元素标签。

     1 public class Car {
     2     private int maxSpeed;
     3     private String brand;
     4     private double price;
     5     public int getMaxSpeed() {
     6         return this.maxSpeed;
     7     }
     8     public void setMaxSpeed(int maxSpeed) {
     9         this.maxSpeed = maxSpeed;
    10     }
    11     public String getBrand() {
    12         return this.brand;
    13     }
    14     public void setBrand(String brand) {
    15         this.brand = brand;
    16     }
    17     public double getPrice() {
    18         return this.price;
    19     }
    20     public void setPrice(double price) {
    21         this.price = price;
    22     }
    23 }

      如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:

    public class CarFactoryBean implements FactoryBean<Car> {
        private String carInfo;
        public Car getObject() throws Exception {
            Car car = new Car();
            String[] infos = carInfo.split(",");
            car.setBrand(infos[0]);
            car.setMaxSpeed(Integer.valueOf(infos[1]));
            car.setPrice(Double.valueOf(infos[2]));
            return car;
        }
        public Class<Car> getObjectType() {
            return Car.class;
        }
        public boolean isSingleton() {
            return false;
        }
        public String getCarInfo() {
            return this.carInfo;
        }
        // 接受逗号分割符设置属性信息
        public void setCarInfo(String carInfo) {
            this.carInfo = carInfo;
        }
    }

      有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:

    1 <bean id="car" class="com.baobaotao.factorybean.CarFactoryBean">
    2     <property name="carInfo" value="法拉利 ,400,2000000"/>
    3 </bean>

      当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");

  • 相关阅读:
    Apache 虚拟主机 VirtualHost 配置
    ajax无线级刷新
    Apache中 RewriteRule 规则参数介绍
    用户注册
    用户登录
    Android 侧滑菜单
    PhontoShop CS6 视频
    ArcGis地图
    Android 汉子转换成拼音
    UTF-8 转 GBK
  • 原文地址:https://www.cnblogs.com/caoyc/p/5624697.html
Copyright © 2011-2022 走看看