实例化bean对象

  • 一、构造方法实例化bean
  • 1、提供无参构造方法
  • 2、在xml文件中配置bean
  • 3、编写代码测试
  • 4、测试结果
  • 二、静态工厂实例化bean
  • 1、创建工厂类
  • 2、配置bean
  • 3、测试代码
  • 4、测试结果
  • 三、实例工厂实例化bean
  • 1、定义实例工厂
  • 2、配置bean对象
  • 3、测试代码
  • 4、测试结果
  • 四、实例工厂实例化bean方式优化方案 - FactoryBean
  • 1、定义FactoryBean类
  • 2、在xml文件中配置bean对象
  • 3、测试代码
  • 4、测试结果


一、构造方法实例化bean

1、提供无参构造方法

public class BeanDaoImpl implements BeanDao {

    public BeanDaoImpl() {
        System.out.println("bean dao constructor running ...");
    }

    public void save() {
        System.out.println("beanDao save...");
    }
}
  • 构造方法是写在接口的实现类中。
  • 权限修饰符可以是public的,也可以是private的,Spring容器都可以访问到。
  • 为什么需要无参构造器?这是因为Spring容器创建bean对象时调用的是该对象的无参构造器。
  • 无参构造方法也可以不写,因为默认会自动提供,前提是并未提供任何构造方法。

2、在xml文件中配置bean

<bean id="beanDao" name="dao,beanDao2" scope="singleton" class="dao.impl.BeanDaoImpl"/>

3、编写代码测试

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanDao dao = (BeanDao) context.getBean("dao");
        dao.save();
    }
}

4、测试结果

bean dao constructor running ...
beanDao save...
  • 结果显示,优先打印了构造方法执行语句,随后才打印了save方法输出语句。
  • 如果没有提供无参构造方法,会报BeanCreationException异常。

二、静态工厂实例化bean

1、创建工厂类

public class BeanDaoFactory {
    public static BeanDao getBeanDao(){
        System.out.println("bean dao factory running ...");
        return new BeanDaoImpl();
    }
}
  • 工厂类其实和我们常写的类没什么区别,都需要遵循类的要求。
  • getBeanDao()方法需要声明为静态static的,可以直接调用。不需要创建类对象使用“对象.方法”的方式调用。
  • 区别于第三种实例化方式——实例工厂实例化bean。

2、配置bean

<bean id="beanDao" class="factory.BeanDaoFactory" factory-method="getBeanDao" />
  • class属性需要指定为对应的工厂类的全限定名
  • 添加“factory-method”属性指定实例化方法名

3、测试代码

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanDao beanDao = (BeanDao) context.getBean("beanDao");
        beanDao.save();
    }
}

4、测试结果

bean dao factory running ...
bean dao constructor running ...
beanDao save...
  • 打印顺序:工厂方法信息 - 构造方法信息 - save方法信息,这也显示出方法间的执行顺序,间接的表现了bean对象的创建过程。

三、实例工厂实例化bean

1、定义实例工厂

public class BeanDaoFactory {
    public BeanDao getBeanDao(){
        System.out.println("bean dao factory running ...");
        return new BeanDaoImpl();
    }
}
  • 细心分析静态工厂和实例工厂的代码,发现几乎一模一样,只是getBeanDao()方法由静态方法变为了非静态方法。
  • 虽然只是一个小小的改变,但却改变了配置bean时的操作。

2、配置bean对象

<!-- 1.配置实例工厂对象 -->
<bean id="beanFactory" class="factory.BeanDaoFactory" />
<!-- 2.配置beanDao对象 -->
<bean id="beanDao" factory-bean="beanFactory" factory-method="getBeanDao" />
  • "factory-bean"属性指向实例工厂对象。
  • 因为实例工厂中实例化方法不是静态的,需要先创建该实例工厂对象,然后才能调用非静态方法。

3、测试代码

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanDao beanDao = (BeanDao) context.getBean("beanDao");
        beanDao.save();
    }
}

4、测试结果

bean dao factory running ...
bean dao constructor running ...
beanDao save...

静态工厂实例化方式和实例工厂实例化方式不是非常常用,了解即可。

四、实例工厂实例化bean方式优化方案 - FactoryBean

为了在配置bean对象中,可以不用再通过“factory-method”的方法刻意指定实例方法,提出来优化方案,在此作为第四种实例化bean方式。

1、定义FactoryBean类

public class BeanDaoFactoryBean implements FactoryBean<BeanDao> {
    public BeanDao getObject() throws Exception {
        return new BeanDaoImpl();
    }

    public Class<?> getObjectType() {
        return BeanDao.class;
    }

    public boolean isSingleton() {
        return true;
    }
}
  • 定义的类需要实现FactoryBean接口中方法。
  • getObject()方法的作用就相当于前面的getBeanDao()方法,其实就是一个实例化方法。
  • getObjectType()方法指定返回的bean对象类型。
  • isSingleton()方法用于设置创建的bean对象的作用范围,是否是单例。如果返回true表示是单例;返回false表示非单例prototype。和在bean标签中添加scope属性作用相同。

2、在xml文件中配置bean对象

<bean id="beanDao" class="factory.BeanDaoFactoryBean"/>

此方式在配置bean对象时,直接将class属性值指定为对应的FactoryBean类即可,无需再配置"factory-bean"属性和”factory-method"属性,非常的方便。

3、测试代码

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanDao beanDao = (BeanDao) context.getBean("beanDao");
        beanDao.save();
    }
}

4、测试结果

bean dao constructor running ...
beanDao save...

该方式之后的使用频率还是挺高的,推荐掌握。