• Spring-bean实例化三种方式


    bean实例化三种方式:

    • 构造方法(常用)!
    • 静态工厂(了解)
    • 实例工厂(了解)
      • FactoryBean(实用)!

    环境准备:

    • 创建一个Maven项目
    • pom.xml添加Spring依赖
    • resources下添加spring的配置文件applicationContext.xml

    1.构造方法实例化(常用)

    步骤1.准备需要的类BookDao和BookDaoImpl类

    package com.hnu.dao.impl;
    import com.hnu.dao.BookDao;
    //实现接口
    public class BookDaoImpl implements BookDao {
        public void save() {
            System.out.println("book dao save ...");
        }
    
    //运行程序,如果控制台有打印构造函数中的输出,说明Spring容器在创建对象的时候也用的是构造函数
    //通过反射的方式获取对象 使用无参构造  无参构造只要当容器被加载就会被执行
    //几遍是private修饰也执行,因为Spring默认使用了构造函数创建对象
        private BookDaoImpl() {
            System.out.println("book dao constructor is running ....");
        }
    
    //有参构造 当即有有参构造又有无参构造,运行会报错
    /*private BookDaoImpl(int i) {
        System.out.println("有参构造 is running ....");
    }*/
    }
    
    
    
    package com.hnu.dao;
    //先创建接口,然后创建实现类,最后在App类中引用实现
    public interface BookDao {
        public void save();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    步骤2:将类配置到Spring容器

    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 bookDaoImpl" class="com.hnu.dao.impl.BookDaoImpl"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    步骤3:编写运行程序

    package com.hnu;
    import com.hnu.dao.BookDao;
    import com.hnu.dao.impl.BookDaoImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AppForInstanceBook {
        public static void main(String[] args) {
            //获得容器
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            //从容器中获取对象进行方法调用
            BookDao  bookDao = (BookDao)ctx.getBean("dao");
            //调用方法
            bookDao.save();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    image-20221109094632439

    运行结果:

    image-20221109095511750

    如果把前面的有参构造注释取消掉,这时候同时存在有参和无参构造,也不会报错

    image-20221109095957563

    但是如果把无参构造注释掉。只留下个有参构造,这时候就要报错了,注意一点对于Spring的不报错,我们要从下往上来看,下面的是一些根本性错误(最核心错误),然后依次往上看,

    比如:

    最后一行:

    Caused by: java.lang.NoSuchMethodException: com.hnu.dao.impl.BookDaoImpl.()

    • Caused by 翻译为引起,即出现错误的原因
    • java.lang.NoSuchMethodException:抛出的异常为没有这样的方法异常
    • com.hnu.dao.impl.BookDaoImpl.():哪个类的哪个方法没有被找到导致的异常,()指定是类的构造方法,即该类的无参构造方法

    如果最后一行错误获取不到错误信息,接下来查看第二层:

    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.hnu.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.hnu.dao.impl.BookDaoImpl.()

    • nested:嵌套的意思,后面的异常内容和最底层的异常是一致的
    • Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.hnu.dao.impl.BookDaoImpl]: No default constructor found;
      • Caused by: 引发
      • BeanInstantiationException:翻译为bean实例化异常
      • No default constructor found:没有一个默认的构造函数被发现

    image-20221109100144433

    2.静态工厂实例化

    首先准备一下环境,划红线的是上一个构造方法的类,不用管

    image-20221109133507744

    步骤1:创建OrderDao和OrderDaoImpl类

    package com.hnu.dao;
    public interface OrderDao {
        public void save();
    }
    
    
    package com.hnu.dao.impl;
    import com.hnu.dao.OrderDao;
    public class OrderDaoImpl implements OrderDao {
        public void save() {
            System.out.println("order dao save...");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    步骤2:创建一个工厂类OrderDaoFactory并提供一个静态方法

    package com.hnu.factory;
    
    import com.hnu.dao.OrderDao;
    import com.hnu.dao.impl.OrderDaoImpl;
    
    //静态工厂实例化,返回一个OrderDaoImpl实现对象
    public class OrderDaoFactory {
        public static OrderDao getOrderDao(){
            return new OrderDaoImpl();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    步骤3:将类配置到Spring容器

    
    <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="orderDao" name="orderDao1" class="com.hnu.factory.OrderDaoFactory" factory-method="getOrderDao"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    步骤4:创建调用运行的执行类AppForInstanceOrder

    package com.hnu;
    import com.hnu.dao.OrderDao;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AppForInstanceOrder {
        public static void main(String[] args) {
            
    //用spring来管理工厂
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            OrderDao orderDao = (OrderDao) ctx.getBean("orderDao1");
            orderDao.save();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    运行结果:

    image-20221109134244346

    大致步骤为:

    先创建接口然后用一个实现类实现接口方法,然后创建一个静态工厂,工厂返回实现类对象,在IOC容器中创建工厂对象,然后在实现类中获取容器并且调用方法

    3.实例工厂与FactoryBean

    1.实例工厂实例化

    环境准备:

    image-20221109153625036

    步骤1:准备一个UserDao和UserDaoImpl类

    package com.hnu.dao;
    public interface UserDao {
        public void save();
    }
    
    
    
    package com.hnu.dao.impl;
    import com.hnu.dao.UserDao;
    public class UserDaoImpl implements UserDao {
        public void save() {
            System.out.println("user dao save ...");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    步骤2:创建一个工厂类UserDaoFactory

    package com.hnu.factory;
    import com.hnu.dao.UserDao;
    import com.hnu.dao.impl.UserDaoImpl;
    public class UserDaoFactory {
        public UserDao getUserDao() {
            //返回一个实现类对象去实现接口中的方法,注意这里不是静态工厂了哦
            return new UserDaoImpl();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    步骤3:将类配置到Spring容器

    
        <bean id="userDaoFactory" class="com.hnu.factory.UserDaoFactory"/>
        <bean id="userDao" factory-bean="userDaoFactory" factory-method="getUserDao"/>
    
    
    • 1
    • 2
    • 3
    • 4

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

    • 创建实例化工厂对象,对应的是第一行配置

    • 调用对象中的方法来创建bean,对应的是第二行配置

      • factory-bean:工厂的实例对象

      • factory-method:工厂对象中的具体创建对象的方法名,对应关系如下:

    image-20221109154039384

    步骤4:创建调用运行的执行类AppForInstanceUser

    package com.hnu;
    import com.hnu.dao.UserDao;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AppForInstanceUser {
        public static void main(String[] args) {
            //获取容器
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            //获取bean对象
            UserDao userDao = (UserDao) ctx.getBean("userDao");
            //执行方法
            userDao.save();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    执行结果:

    image-20221109154321279

    2.FactoryBean使用

    简化实例工厂开发

    创建一个UserDaoFactoryBean工厂类

    image-20221109155450816

    package com.hnu.factory;
    import com.hnu.dao.UserDao;
    import com.hnu.dao.impl.UserDaoImpl;
    import org.springframework.beans.factory.FactoryBean;
    
    import javax.jws.soap.SOAPBinding;
    
    //使用接口的形式,实现工厂模式 实例化Bean
    public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    
        //替代原来实例工厂中创建对象的方法
        public UserDao getObject() throws Exception {
            return new UserDaoImpl();
        }
        //返回所创建类的class对象
        public Class<?> getObjectType() {
            return UserDao.class;
        }
    
        //创建的对象是否是单例化
        public boolean isSingleton() {
            return false;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    将类配置到Spring容器

    
    <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="userDao" class="com.hnu.factory.UserDaoFactoryBean"/>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    运行类和前面实例化工厂一样,这里验证创建的对象是否是单例化

    package com.hnu;
    
    import com.hnu.dao.UserDao;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AppForInstanceUser {
        public static void main(String[] args) {
            //获取容器
            ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
            //获取bean对象
            UserDao userDao = (UserDao) ctx.getBean("userDao");
            UserDao userDao1 = (UserDao) ctx.getBean("userDao");
            //执行方法
            userDao.save();
            System.out.println(userDao);
            System.out.println(userDao1);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    运行结果:

    image-20221109155819845

  • 相关阅读:
    关于pycharm打开时一直加载中的解决办法
    制作耳机壳的UV树脂和塑料材质哪一个成本更高一些?
    无需添加udid,ios企业证书的自助生成方法
    Java中CAS算法的集中体现:Atomic原子类库,你了解吗?
    JUC并发编程——JMM详解(基于狂神说得到学习笔记)
    为什么你的自媒体账号涨粉很慢?
    附录4-JS关键字
    MFC实现关闭窗口,弹出确认提示
    【11.2】【VP】Codeforces Round #727 (Div. 2)
    条件期望:Conditional Expectation 举例详解之入门之入门之草履虫都说听懂了
  • 原文地址:https://blog.csdn.net/weixin_51470901/article/details/127771696