详解Spring Bean的配置方式与实例化
作者:倔强的牛角 发布时间:2022-01-13 05:47:51
一、 Spring Bean 配置方式
由 Spring IoC 容器管理的对象称为 Bean,Bean 配置方式有两种:配置文件开发和注解开发
配置文件开发
Spring 配置文件支持两种格式:xml和properties,此教程以xml配置文件讲解。
XML 配置文件的根元素是 <beans>,该元素包含了多个子元素 <bean>。每一个 <bean> 元素都定义了一个 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 容器创建对象时用的也是构造方法
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底层用的是反射,访问到类中的私有构造方法。
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底层使用的是类的无参构造方法。
4.画个图总结下:Spring 配置文件中 bean 标签的 id 和类的全限定名一一对应,所以 Spring IoC容器的 getBean 方法其实就是先根据 bean 的 id 获取该类的全限定名,然后再利用反射根据类的全限定名创建对象并返回。
静态工厂实例化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();
}
}
看见运行结果,输出以下语句
实例工厂实例化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.运行程序和静态工厂一样,查看运行结果
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);
}
}
来源:https://juejin.cn/post/7102062596802478087


猜你喜欢
- 前言前几篇文章着重介绍了后端服务数据库和多线程并行处理优化,并示例了改造前后的伪代码逻辑。当然了,优化是无止境的,前人栽树后人乘凉。作为我们
- Spring 配置文件报错:元素 "context:component-scan" 的前缀 "context&
- 1.分页类package org.zh.basic;/** * 页面类 * * @author keven&
- JMM与问题引入为啥先说JMM,因为CAS的实现类中维护的变量都被volatile修饰, 这个volatile 是遵循JMM规范(不是百分百
- 本文将通过AOP的方式实现一个相对更加简易灵活的API安全认证服务。我们先看实现,然后介绍和分析AOP基本原理和常用术语。一、Authori
- 本文为大家分享两个实例,相信大家一定会喜欢。实例1:随机生成验证码图片并将之输出为一个png文件效果图:import java.awt.Co
- 本文实例汇总了C#常用GDI+文字操作,包含了文字的投影、倒影、旋转等常见的效果,在进行C#应用程序开发中有不错的实用价值。分享给大家供大家
- 引言Java反射机制是一个非常强大的功能,在很多大型项目比如Spring, Mybatis都可以看见反射的身影。通过反射机制我们可以在运行期
- 利用 Spring 工厂加载机制,实例化 ApplicationListener 实现类,并排序对象集合创建应用事件 * 创建类实现接口Ap
- 网络中数据传输经常是xml或者json,现在做的一个项目之前调其他系统接口都是返回的xml格式,刚刚遇到一个返回json格式数据的接口,通过
- 废话不多说了,直接给大家贴代码了,具体代码如所示:/** * get方法的文件下载 * <p> &n
- Excelapache 为 java开发者们提供了一套excel表格读写的工具:POI ,对于一个小白来说每次读写使用POI需要写一套复杂的
- 在Android开发中很多时候会遇到一屏显示不下所有内容的现象,那大家也知道这个时候肯定会想到用scrollview来进行滚屏显示。这个时候
- 本文实例讲述了C#获取字符串后几位数的方法。分享给大家供大家参考。具体实现方法如下:#region 获取后几位数 public string
- 前言本篇文章讲的是Kotlin 自定义view之实现标尺控件Ruler,以选择身高、体重等。开发中,当我们需要获取用户的身高和体重等信息时,
- 说在前面:老项目、大项目适配Android X 注意了,一定要谨慎、谨慎、再谨慎。项目中用到的第三方库多的话会很麻烦,有些第三方库还没有适配
- 提到输入参数的基本验证(非空、长度、大小、格式…),在以前我们还是通过手写代码,各种if、else、StringUtils.isEmpty、
- 在spring的一个controller中要把参数传到页面,只要配置视图解析器,把参数添加到Model中,在页面用el表达式就可以取到。但是
- 前言大家在学习Java的过程中,或者工作中,始终都绕不开集合。在单线程环境下,ArrayList就可以满足要求。多线程时,我们可以使用Cop
- 本文基于shardingsphere-jdbc-core-spring-boot-starter 5.0.0,请注意不同版本的shardin