Spring官方文档: Bean 实例化
一、通过构造函数实例化

验证是否是通过构造函数实例化
在 BookDaoImpl 中创建构造函数,并在构造函数中输出一段话。
1 2 3 4 5 6 7 8 9 10 11
   | public class BookDaoImpl implements BookDao {
      public BookDaoImpl(){         System.out.println("book dao constructor is Running...");     }
      @Override     public void save() {         System.out.println("book dao save !!!");     } }
 
  | 
 
控制台输出
可以看到,在控制台已经输出了这段话
App 启动类调用为:5. bean 基础配置 中的实现代码

问题:
- 如果将构造函数改为 
private ,Spring 还能进行实例化吗?
- 可以,因为 Spring 是通过 反射 获取的对象实例
 
 
- 如果将构造函数改为有参构造函数,Spring 还能进行实例化吗?
- 如果没有无参构造的话,此时会抛出异常,如果有无参构造则还可以正常实例化。
 
 
记录一个异常

如果出现了 NoSuchMethodException,则说明 Spring 没有找到某个方法 cn.pangcy.dao.impl.BookDaoImpl.<init>() 则说明了没有在 BookDaoImpl 中找到 init 即无参构造方法。
记录一个阅读 Spring 报错信息的技巧
阅读 Spring 报错信息要从最后一行往上看,因为 Spring 会从下将每一行错误信息携带道尾部输出当前行错误
如上图异常中,最后一行 NoSuchMethodException, 在倒数第二行 BeanInstantiationException 尾部出现,而 BeanInstantiationException 中错误信息会被追加到第一个错误信息的尾部出现。
二、使用静态工厂实例化

静态工厂
factory/BookDaoFactory
1 2 3 4 5 6
   | public class BookDaoFactory {     public static BookDao getBookDao(){         System.out.println("factory setup ....");         return new BookDaoImpl();     } }
 
  | 
 
配置
applicationContext.xml
- 改变一: class 从原本指向 
cn.pangcy.dao.impl.BookDaoImpl 改为 cn.pangcy.factory.BookDaoFactory 
- 改变二:  bean 上添加 
factory-method 指定运行的静态工厂函数 
如果不指定 factory-method ,那么实例化出来的是这个工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14
   | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 	
 
 
      <bean id="bookDao" name="dao" class="cn.pangcy.factory.BookDaoFactory" factory-method="getBookDao"/>
      <bean id="bookService" name="service bookService2 bookEbi" class="cn.pangcy.service.impl.BookServiceImpl" scope="prototype">         <property name="bookDao" ref="dao"/>     </bean> </beans>
 
  | 
 
三、实例工厂初始化对象

实例工厂
factory/OrderDaoFactory
和静态工厂的区别是,他不是一个静态方法
1 2 3 4 5
   | public class OrderDaoFactory {     public OrderDao getOrderDao(){         return new OrderDaoImpl();     } }
 
  | 
 
配置
applicationContext.xml
- 改变一:需要新增一个 bean 作为这个工厂的 bean : 
orderDaoFactory 
- 改变二:Dao bean 中,不需要指定 
class 了,改为指定 factory-bean 
- 改变二:Dao bean 中,依旧需要像静态工厂一样指定 
factory-mehod 
1 2 3 4 5 6 7 8 9 10 11 12
   | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
      <bean id="orderDaoFactory" class="cn.pangcy.factory.OrderDaoFactory"/>     <bean id="orderDao" name="dao" factory-bean="orderDaoFactory" factory-method="getOrderDao"/>
      <bean id="orderService" class="cn.pangcy.service.impl.OrderServiceImpl" scope="prototype">         <property name="orderDao" ref="orderDao"/>     </bean> </beans>
 
  | 
 
四、使用 FactoryBean 初始化对象

实现 FactoryBean
通过实现 FactoryBean, 实例化 Bean
FactoryBean 主要需要重写 getObject 和 getObjectType 两个方法,getObject 代替原始实例工厂中创建对象的方法,getObjectType 返回对象的类型
isSingleton 设置是否单例的默认值,如果在 bean 中配置了 scoped 则以  bean 中配置为准
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | public class OrderDaoFactoryBean implements FactoryBean<OrderDao> {
           @Override     public OrderDao getObject() throws Exception {         return new OrderDaoImpl();     }
      @Override     public Class<?> getObjectType() {         return OrderDao.class;     }
                @Override     public boolean isSingleton() {         return false;      } }
 
  | 
 
配置
applicationContext.xml
配置方式和常规构造方法配置一致。
1 2 3 4 5 6 7 8 9 10 11
   | <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
           <bean id="orderDaoFactory" name="dao" class="cn.pangcy.factory.OrderDaoFactoryBean"/>     <bean id="orderService" class="cn.pangcy.service.impl.OrderServiceImpl" >         <property name="orderDao" ref="dao"/>     </bean> </beans>
 
  |