写点什么

【Spring 学习笔记 (二)】Spring Bean 配置方式 与 Spring Bean 实例化

作者:倔强的牛角
  • 2022 年 6 月 03 日
  • 本文字数:3318 字

    阅读完需:约 11 分钟

【Spring 学习笔记(二)】Spring Bean 配置方式 与Spring Bean实例化

写在前面😘

大一电子信息工程新生,请多多关照,希望能在 InfoQ 社区记录自己的学习历程!

【Spring 学习笔记】 系列教程基于 Spring 5.2.10.RELEASE讲解 ,部分图片来源于网络,侵权删。

一、 Spring Bean 配置方式

由 Spring IoC 容器管理的对象称为 Bean,Bean 配置方式有两种:配置文件开发注解开发

1、配置文件开发

Spring 配置文件支持两种格式:xml 和 properties,此教程以 xml 配置文件讲解。


XML 配置文件的根元素是 <beans>,该元素包含了多个子元素 <bean>。每一个 <bean> 元素都定义了一个 Bean



  • XML 配置文件常用元素表👇


2、注解开发

先插个眼在这,过几天会发一篇文章详细介绍

二、Spring Bean 实例化

通过控制反转,对象的创建权就交给了 IoC 容器,但是容器是如何来创建对象的呢?

bean 本质上就是对象,对象在 new 的时候会使用构造方法,创建 bean 其实也是使用构造方法完成的。

实例化 bean 的三种方式:构造方法,静态工厂实例工厂

1、环境准备

  1. 准备一个UserDao接口和一个UserDaoImpl实现类


//UserDao接口public interface UserDao {    public void say();}//UserDaoImpl实现类public class UserDaoImpl implements UserDao {    @Override    public void say() {        System.out.println("Hello,I am BigHorn!");    }}
复制代码


  1. 编写 spring 配置文件


<bean id="userDao" class="com.bighorn.dao.impl.UserDaoImpl"/>
复制代码


  1. 编写运行程序


public class App {    public static void main(String[] args) {        //获取IoC容器        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        //从容器中获取对象        UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class);        userDao.say();    }}
复制代码

2、构造方法实例化 Bean

第一种实例化 bean 的方法:构造方法实例化,这也是最常用的方法,因为类都会提供默认的构造方法。下面来测试下


  1. 在 UserDaoImpl 类中添加一个无参构造方法,并打印一句话,方便观察结果。


public class UserDaoImpl implements UserDao {    //添加一个无参构造方法    public UserDaoImpl() {        System.out.println("这是UserDaoImpl的无参构造方法");    }
@Override public void say() { System.out.println("Hello,I am BigHorn!"); }}
复制代码


可以在控制台看到输出结果,说明 Spring IoC 容器创建对象时用的也是构造方法



  1. 将构造方法改成 private 测试


public class UserDaoImpl implements UserDao {    //将构造方法改成private    private UserDaoImpl() {        System.out.println("这是UserDaoImpl的无参构造方法");    }
@Override public void say() { System.out.println("Hello,I am BigHorn!"); }}
复制代码


发现还可以运行成功,这说明 Spring 底层用的是反射,访问到类中的私有构造方法。



  1. 将无参构造方法换成有参构造方法


public class UserDaoImpl implements UserDao {    //将无参构造方法换成有参构造方法    private UserDaoImpl(int i) {        System.out.println("这是UserDaoImpl的无参构造方法");    }    @Override    public void say() {        System.out.println("Hello,I am BigHorn!");    }}
复制代码


程序会报java.lang.NoSuchMethodException错,说明 Spring 底层使用的是类的无参构造方法



  1. 画个图总结下:Spring 配置文件中 bean 标签的 id 和类的全限定名一一对应,所以 Spring IoC 容器的 getBean 方法其实就是先根据 bean 的 id 获取该类的全限定名,然后再利用反射根据类的全限定名创建对象并返回。


3、静态工厂实例化 Bean

第二种实例化 Bean 的方法:静态工厂实例化

了解即可,一般是用来兼容早期的一些老系统。


  1. 创建一个 UserDaoFactory 工厂类并提供一个静态方法


//UserDao接口public interface UserDao {    public void say();}//UserDaoImpl实现类public class UserDaoImpl implements UserDao {    public UserDaoImpl() {        System.out.println("这是UserDaoImpl的无参构造方法");    }    @Override    public void say() {        System.out.println("Hello,I am BigHorn!");    }}//UserDaoFactory工厂类public class UserDaoFactory {    //静态工厂创建对象    public static UserDao getUserDao(){        System.out.println("这是静态工厂实例化Bean");        return new UserDaoImpl();    }}
复制代码


  1. 编写 spring 配置文件


<!--        class:工厂类全类名        factory-method:工厂创建对象的方法名     --><bean id="userDao" class="com.bighorn.factory.UserDaoFactory" factory-method="getUserDao"/>
复制代码


  1. 编写运行程序


public class App {    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {        //获取IoC容器        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        //从容器中获取对象        UserDaoImpl userDao = context.getBean("userDao", UserDaoImpl.class);        userDao.say();    }}
复制代码


看见运行结果,输出以下语句


4、实例工厂实例化 Bean

第二种实例化 Bean 的方法:实例工厂实例化

了解即可,其实和静态工厂差不多。只不过静态工厂可以直接通过静态方法创建 bean,实例工厂要先 new 一个实例工厂对象,然后再通过这个实例工厂对象创建 bean


  1. 创建一个UserDaoFactory工厂类,和静态工厂不一样的是,实力工厂提供的是一个普通方法


//UserDaoFactory工厂类public class UserDaoFactory {    //实例工厂创建对象    public  UserDao getUserDao(){        System.out.println("这是实例工厂实例化Bean");        return new UserDaoImpl();    }}
复制代码


  1. 编写 spring 配置文件


<!--         userFactory:工厂的实例对象         factory-bean:指向工厂的实例对象         factory-method:工厂对象中创建对象的方法名    --><bean id="userFactory" class="com.bighorn.factory.UserDaoFactory"/><bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/>
复制代码


  1. 运行程序和静态工厂一样,查看运行结果


5、FactoryBean

实例工厂的方法听麻烦的,其实 spring 框架为我们一种实例工厂的方式:FactoryBean,比较实用,用来整合其他框架

我们只需要实现 FactoryBean 接口即可简化开发,下面来介绍下它的具体使用方法


  1. 创建 UserDaoFactoryBean 类,实现 FactoryBean 接口中的三个方法:

  2. boolean isSingleton():设置 bean 作用域,默认 true 表示单例,false 表示非单例

  3. T getObject() throws Exception:返回的是 bean 实例对象

  4. Class<?> getObjectType():返回的是被创建类的 Class 对象


public class UserDaoFactoryBean implements FactoryBean<UserDao> {    //bean作用域:默认true表示单例    public boolean isSingleton() {        return true;    }    //代替实例工厂中创建对象的方法    public UserDao getObject() throws Exception {        System.out.println("这是FactoryBean实例化bean");        return new UserDaoImpl();    }    //返回所创建类的Class对象    public Class<?> getObjectType() {        return UserDao.class;    }}
复制代码


  1. 编写 spring 配置文件


<bean id="userDao" class="com.bighorn.factory.UserDaoFactoryBean"/>
复制代码


  1. 编写运行程序


public class App {    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {        //获取IoC容器        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");        //从容器中获取对象        UserDaoImpl userDao1 = context.getBean("userDao", UserDaoImpl.class);        UserDaoImpl userDao2 = context.getBean("userDao", UserDaoImpl.class);        System.out.println(userDao1);        System.out.println(userDao2);    }}
复制代码


写在后面🍻

感谢观看啦✨

有什么不足,欢迎指出哦💖

发布于: 2022 年 06 月 03 日阅读数: 21
用户头像

把学问造就,还期身健行优。 2022.06.02 加入

大一在读,电子信息工程专业。 希望在InfoQ写作社区记录自己的学习历程!

评论

发布
暂无评论
【Spring 学习笔记(二)】Spring Bean 配置方式 与Spring Bean实例化_6月月更_倔强的牛角_InfoQ写作社区