您的位置 首页 java

「JavaWeb 3-2」IOC-bean的实例化

3.2 bean 实例化

Spring 中创建 bean 对象时使用 构造方法 来实现的,有三种创建方式

3.2.1 构造方法实例化

1. 示例

  package dao;
 
 /**
  * @Author 晨默
  * @Date 2022/9/29 16:25
  */
 public interface BookDao {
     public  void  save();
 }
   
  package dao.impl;
 
 import dao.BookDao;
 
 /**
  * @Author 晨默
  * @Date 2022/9/29 16:39
  */
 public class BookDaoImpl implements BookDao {
     public BookDaoImpl(){
         System.out.println("book dao constructor is running...");
     }
     public void save(){
         System.out.println("book dao save....");
     }
 }
   
  <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "#34;>
 <beans>
     <!-- bean标签标示配置bean
          id属性:给bean标示
           Class 属性:给bean定义类型
     -->
     <bean id="bookDao" name="dao" class="dao.impl.BookDaoImpl"/>
     <bean id="bookService" name="service service4 bookEbi" class="service.impl.BookServiceImpl">
         <!-- 配置 server 与 dao 的关系-->
         <!-- property 标签表示配置当前bean的属性
              name 属性表示配置哪一个具体的属性
              ref 属性表示参照哪一个 bean
         -->
         <property name="bookDao" ref="bookDao"/>
     </bean>
 </beans>  
  import dao.BookDao;
 import org.springframework.context.ApplicationContext;
 import org. spring framework.context.support.ClassPathXmlApplicationContext;
 import service.BookService;
 
 /**
  * @Author 晨默
  * @Date 2022/9/29 18:56
  */
 public class AppForInstanceBook {
     public  static  void main(String[] args) {
         // 获取 IOC 容器
         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
         // 从 IOC 容器中获取对象进行方法调用
         BookDao bookDao = (BookDao) ctx.getBean("bookDao");
         bookDao.save();
     }
 }
   

测试结果如下:

由测试结果:说明 Spring容器在创建对象的时候也走的是构造函数

2.将构造函数改成 private 进行测试

  package dao.impl;
 
 import dao.BookDao;
 
 /**
  * @Author 晨默
  * @Date 2022/9/29 16:39
  */
 public class BookDaoImpl implements BookDao {
     private BookDaoImpl(){
         System.out.println("book dao constructor is running...");
     }
     public void save(){
         System.out.println("book dao save....");
     }
 }  

测试结果:

测试结果说明内部走的依然是 构造函数 ,能访问到类中的私有构造方法,显而易见 Spring底层用的是反射

3. 构造函数添加参数测试

  package dao.impl;
 
 import dao.BookDao;
 
 /**
  * @Author 晨默
  * @Date 2022/9/29 16:39
  */
 public class BookDaoImpl implements BookDao {
     public BookDaoImpl(int i){
         System.out.println("book dao constructor is running...");
     }
     public void save(){
         System.out.println("book dao save....");
     }
 }
   

运行程序会报错:

说明Spring底层使用的是类的无参数构造方法

3.2.2 静态工厂实例化

1. 工厂方式创建 bean

  public interface OrderDao {
     public void save();
 }  
  public class OrderDaoImpl implements OrderDao {
     public void save(){
         System.out.println("order dao save...");
     }
 }  
  // 静态工厂创建对象
 public class OrderDaoFactory {
     public static OrderDao getOrderDao(){
         return new OrderDaoImpl();
     }
 }  
  public class AppForInstanceOrder {
     public static void main(String[] args) {
         // 通过静态工厂创建对象
         OrderDao orderDao = OrderDaoFactory.getOrderDao();
         orderDao.save();
     }
 }  

测试结果:

2. 静态工厂实例化

实现步骤如下:

1. 在 spring 的配置文件 application.xml 中配置

  <bean id="orderDao" class="factory.OrderDaoFactory" factory-method="getOrderDao"/>  
  • class :工厂类的类全名
  • factory-mehod :具体工厂类中创建对象的方法名

对应关系如下:

2. 获取 IOC 容器,获取 bean 对象,进行测试

  public class AppForInstanceOrder {
     public static void main(String[] args) {
         /*// 通过静态工厂创建对象
         OrderDao orderDao = OrderDaoFactory.getOrderDao();
         orderDao.save();*/
         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
         OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");
         orderDao.save();
     }
 }  

测试结果如下:

3.2.3 实例工厂与 FactoryBean

1. 环境准备

  public interface UserDao {
     public void save();
 }  
  public class UserDaoImpl implements UserDao {
     public void save(){
         System.out.println("user dao save....");
     }
 }  
  public class UserDaoFactory {
     public UserDao getUserDao(){
         return new UserDaoImpl();
     }
 }
   
  public class AppForInstanceUser {
     public static void main(String[] args) {
         // 创建实力工厂对象
         UserDaoFactory userDaoFactory = new UserDaoFactory();
         // 通过实例工厂创建对象
         UserDao userDao = userDaoFactory.getUserDao();
         userDao.save();
     }
 }  

测试结果如下:

2. 实例工厂实例化

1. spring 配置文件中添加配置

  <!-- 方式三:实力工厂实例化 -->
 <bean id="userFactory" class="factory.UserDaoFactory"/>
 <bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>  

实例化工厂运行的顺序是:

  • 创建实例化工厂对象,对应的是第一行配置
  • 调用对象中的方法来创建 bean,对应的是第二行配置
    • factory-bean :工厂的实例化对象
    • factory-method :工厂对象中的具体创建对象的方法名,对应关系如下:

2. 在 AppForInstanceUser 运行类,使用从 IOC 容器中获取 bean 的方法进行测试

  public class AppForInstanceUser {
     public static void main(String[] args) {
         /*// 创建实力工厂对象
         UserDaoFactory userDaoFactory = new UserDaoFactory();
         // 通过实例工厂创建对象
         UserDao userDao = userDaoFactory.getUserDao();
         userDao.save();*/
         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
         UserDao userDao = (UserDao) ctx.getBean("userDao");
         userDao.save();
     }
 }  

测试结果如下:

3. FactoryBean 的使用

Spring 为了简化这种配置方式就提供了一种叫 FactoryBean 的方式来简化开发

1. 具体使用步骤

  • 创建一个 UserDaoFactoryBean 的类,实现 FactoryBean 接口,重写接口方法
    • getObject :在方法中进行对象的创建并返回
    • getObjectType :返回被创建的类的 Class 对象
    • isSingleton :设置对象是否是单例,默认是否,即不设置单例
  public class UserDaoFactoryBean implements FactoryBean {
     @Override
     public UserDao getObject() throws  Exception  {
         return new UserDaoImpl();
     }
 
     @Override
     public Class<?> getObjectType() {
         return UserDao.class;
     }
 
     @Override
     public boolean isSingleton() {
         return false;
     }
 }  
  • 在 Spring 的配置文件中进行配置
  <bean id="userDao" class="factory.UserDaoFactoryBean"/>  

测试结果如下:

文章来源:智云一二三科技

文章标题:「JavaWeb 3-2」IOC-bean的实例化

文章地址:https://www.zhihuclub.com/175622.shtml

关于作者: 智云科技

热门文章

网站地图