详解Spring Bean的配置方式与实例化


Posted in Java/Android onJune 10, 2022

一、 Spring Bean 配置方式

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

配置文件开发

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

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

详解Spring Bean的配置方式与实例化

XML 配置文件常用元素表

属性名称 描述
id Bean 的唯一标识符,Spring IoC 容器对 Bean 的配置和管理都通过该属性完成。
name Bean 的别名,可以通过 name 属性为同一个 Bean 同时指定多个名称,每个名称之间用逗号或分号隔开。
class 指定了Bean 的具体实现类,它必须是一个类的全限定名。
scope Bean 的作用域,属性值可以为 singleton(单例)、prototype(原型)、request、session 和 global Session。默认值是 singleton。

注解开发

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

二、Spring Bean实例化

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

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

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

环境准备

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!");
    }
}

2.编写spring配置文件

<bean id="userDao" class="com.bighorn.dao.impl.UserDaoImpl"/>

3.编写运行程序

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();
    }
}

构造方法实例化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 容器创建对象时用的也是构造方法

详解Spring Bean的配置方式与实例化

2.将构造方法改成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底层用的是反射,访问到类中的私有构造方法。

详解Spring Bean的配置方式与实例化

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

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底层使用的是类的无参构造方法

详解Spring Bean的配置方式与实例化

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

详解Spring Bean的配置方式与实例化

静态工厂实例化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();
    }
}

2.编写spring配置文件

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

3.编写运行程序

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();
    }
}

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

详解Spring Bean的配置方式与实例化

实例工厂实例化Bean

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

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

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

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

2.编写spring配置文件

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

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

详解Spring Bean的配置方式与实例化

FactoryBean

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

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

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

  • boolean isSingleton():设置bean作用域,默认true表示单例,false表示非单例
  • T getObject() throws Exception:返回的是bean实例对象
  • 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;
    }
}

2.编写spring配置文件

<bean id="userDao" class="com.bighorn.factory.UserDaoFactoryBean"/>

3.编写运行程序

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);
    }
}

详解Spring Bean的配置方式与实例化

以上就是详解Spring Bean的配置方式与实例化的详细内容,更多关于Spring Bean配置方式 实例化的资料请关注三水点靠木其它相关文章!


Tags in this post...

Java/Android 相关文章推荐
Java新手教程之ArrayList的基本使用
Jun 20 Java/Android
详解Java实现数据结构之并查集
Jun 23 Java/Android
解决SpringBoot跨域的三种方式
Jun 26 Java/Android
Java中PriorityQueue实现最小堆和最大堆的用法
Jun 27 Java/Android
分析JVM源码之Thread.interrupt系统级别线程打断
Jun 29 Java/Android
Spring mvc是如何实现与数据库的前后端的连接操作的?
Jun 30 Java/Android
Java org.w3c.dom.Document 类方法引用报错
Aug 07 Java/Android
Java字符缓冲流BufferedWriter
Apr 09 Java/Android
Java版 简易五子棋小游戏
May 04 Java/Android
Android Studio 计算器开发
May 20 Java/Android
详解Flutter自定义应用程序内键盘的实现方法
Jun 14 Java/Android
Springboot中如何自动转JSON输出
Jun 16 Java/Android
Spring JPA 增加字段执行异常问题及解决
Jun 10 #Java/Android
Android开发手册自定义Switch开关按钮控件
Jun 10 #Java/Android
java实现面板之间切换功能
Jun 10 #Java/Android
Spring Boot项目如何优雅实现Excel导入与导出功能
Jun 10 #Java/Android
解决spring.thymeleaf.cache=false不起作用的问题
Jun 10 #Java/Android
Android开发手册Chip监听及ChipGroup监听
Jun 10 #Java/Android
Java实现带图形界面的聊天程序
Jun 10 #Java/Android
You might like
最令PHP初学者们头痛的十四个问题
2007/01/15 PHP
php下实现伪 url 的超简单方法[转]
2007/09/24 PHP
PHP图片验证码制作实现分享(全)
2012/05/10 PHP
Memcached常用命令以及使用说明详解
2013/06/27 PHP
php实现爬取和分析知乎用户数据
2016/01/26 PHP
php解析xml 的四种简单方法(附实例)
2016/07/11 PHP
php使用函数pathinfo()、parse_url()和basename()解析URL
2016/11/25 PHP
php str_replace替换指定次数的方法详解
2017/05/05 PHP
php获取手机端的号码以及ip地址实例代码
2018/09/12 PHP
一个用js实现的页内搜索代码
2007/05/23 Javascript
JavaScript语法着色引擎(demo及打包文件下载)
2007/06/13 Javascript
jquery ajax,ashx,json的用法总结
2014/02/12 Javascript
chrome浏览器当表单自动填充时如何去除浏览器自动添加的默认样式
2015/10/09 Javascript
JS 实现倒计时数字时钟效果【附实例代码】
2016/03/30 Javascript
vue.js表格组件开发的实例详解
2016/10/12 Javascript
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
nodejs 十六进制字符串型数据与btye型数据相互转换
2018/07/30 NodeJs
Vue 路由切换时页面内容没有重新加载的解决方法
2018/09/01 Javascript
vue.js 实现点击按钮动态添加li的方法
2018/09/07 Javascript
ES6中Set和Map数据结构,Map与其它数据结构互相转换操作实例详解
2019/02/28 Javascript
nodejs微信开发之授权登录+获取用户信息
2019/03/17 NodeJs
基于 vue-skeleton-webpack-plugin 的骨架屏实战
2019/08/05 Javascript
vue路由拦截器和请求拦截器知识点总结
2019/11/08 Javascript
[03:03]2014DOTA2西雅图国际邀请赛 Alliance战队巡礼
2014/07/07 DOTA
[01:00]DOTA2 store: Collection of Artisan's Wonders
2015/08/12 DOTA
Python使用PyCrypto实现AES加密功能示例
2017/05/22 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
tensorflow 保存模型和取出中间权重例子
2020/01/24 Python
Python编程快速上手——选择性拷贝操作案例分析
2020/02/28 Python
在Ubuntu 20.04中安装Pycharm 2020.1的图文教程
2020/04/30 Python
护理专业毕业生推荐信
2013/10/31 职场文书
销售总经理岗位职责
2014/03/15 职场文书
片区教研活动总结
2014/07/02 职场文书
军事博物馆观后感
2015/06/05 职场文书
实例详解Python的进程,线程和协程
2022/03/13 Python
Vue+Flask实现图片传输功能
2022/04/01 Vue.js