Spring 使用介绍(二)—— IoC
一、简单使用:Hello World实例
1、maven添加依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency>
2、定义接口和类
public interface Hello { void sayHello(); }
public class HelloImpl implements Hello { @Override public void sayHello() { System.out.println("hello boy!"); } }
3、spring配置,实例化bean
<?xml 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-3.0.xsd"> <!-- id 表示你这个组件的名字,class表示组件类 --> <bean id="hello" class="cn.matt.spring.ioc.HelloImpl"></bean> </beans>
4、测试类
public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml"); Hello hello = context.getBean(Hello.class); hello.sayHello(); } }
// 输出:hello boy!
说明:
beans的概念
由IoC容器管理的那些组成你应用程序的对象我们就叫它Bean, Bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了
ApplicationContext
ApplicationContext 继承自BeanFactory,可访问bean,有两个实现类:
ClassPathXmlApplicationContext 从classpath获取配置文件
FileSystemXmlApplicationContext 从文件系统获取配置文件
二、配置文件元素
在命名空间(http://www.springframework.org/schema/beans)下,Spring配置文件主要有四个元素:
<!-- 说明信息 --> <description>说明信息</description> <!-- bean定义 --> <bean id="hello" class="cn.matt.spring.ioc.HelloImpl"></bean> <!-- bean别名 --> <alias name="hello" alias="helloAlias"/> <!-- 导入其他配置文件 --> <import resource="other.xml"/>
说明:
1、多个配置文件,除了使用<import>导入,也可以使用ClassPathXmlApplicationContext支持多个文件的构造方法
2、bean的命名,应符合Java命名规范,采用驼峰式命名法
3、bean名称须唯一,可采用name或id属性指定,但规范的做法是使用id
三、bean的构造
bean的构造有三种方式:
1、构造器方式
<!-- 默认构造器 --> <bean id="hello" class="cn.matt.spring.ioc.HelloImpl"></bean> <!-- 构造器 --> <bean id="hello2" class="cn.matt.spring.ioc.HelloImpl"> <constructor-arg index="0" value="kevin"/> </bean>
2、静态工厂方式
public class HelloStaticFactory { public static Hello getInstance(String name) { return new HelloImpl(name); } }
<bean id="hello3" class="cn.matt.spring.ioc.HelloStaticFactory" factory-method="getInstance"> <constructor-arg index="0" value="hello kevin"/> </bean>
3、实例工厂方式
public class HelloFactory { public Hello getInstance(String name) { return new HelloImpl(name); } }
<bean id="helloFactory" class="cn.matt.spring.ioc.HelloFactory"></bean> <bean id="hello4" factory-bean="helloFactory" factory-method="getInstance"> <constructor-arg index="0" value="hello kevin"/> </bean>
使用<constructor-arg>指定参数的方式有三种:
- 参数索引,如上
- 参数类型,除基本类型,须指定全限定名,如:<constructor-arg type="java.lang.String" value="Hello World!"/>
- 参数名,须编译时添加变量名信息,如:<constructor-arg name="message" value="Hello World!"/>
四、依赖注入
1、setter注入
<bean id="hello5" class="cn.matt.spring.ioc.HelloImpl"> <property name="name" value="Hello World!"/> <property name="age" value="10"/> </bean>
setter注入要求属性必须有setter方法,且方法名要遵循“JavaBean getter/setter 方法命名约定”
JavaBean本质是一个POJO类,但具有以下限制:
- 有公共的无参构造器
- 属性是private访问级别,不建议public
- 属性必要时通过一组setter(修改器)和getter(访问器)方法来访问
- setter方法,以“set” 开头,后跟首字母大写的属性名,如“setMesssage”,只有一个方法参数,方法返回值为“void”
- getter方法,以“get”开头,对于boolean类型一般以“is”开头,后跟首字母大写的属性名,如“getMesssage”,“isOk”
- 属性有连续两个大写字母开头,如“URL”,则setter/getter方法为:“setURL”和“getURL”
2、数组
<bean id="hello8" class="cn.matt.spring.ioc.HelloImpl"> <property name="wordArray"> <array value-type="java.lang.String"> <value>item1</value> <value>item2</value> </array> </property> </bean>
value-type 默认为java.lang.String,因此可省略
3、集合类注入
集合类注入分为list和set,对于collection类型,两者均可注入
<!-- list注入 --> <bean id="hello6" class="cn.matt.spring.ioc.HelloImpl"> <property name="words"> <list value-type="java.lang.String"> <value>hi</value> <value>pretty</value> </list> </property> </bean> <!--set注入 --> <bean id="hello7" class="cn.matt.spring.ioc.HelloImpl"> <property name="wordSet"> <set value-type="java.lang.String"> <value>hi</value> <value>pretty</value> </set> </property> </bean>
4、Map注入
<bean id="hello9" class="cn.matt.spring.ioc.HelloImpl"> <property name="wordMap"> <map key-type="java.lang.String" value-type="java.lang.String"> <entry key="a" value="abc" /> <entry key="x" value="xyz" /> </map> </property> </bean>
5、Properties注入
Properties的key、value均为String,不可变
<bean id="hello10" class="cn.matt.spring.ioc.HelloImpl"> <property name="properties"> <props> <prop key="a">abc</prop> <prop key="x">xyz</prop> </props> </property> </bean>
6、注入bean
<bean id="bean1" class="java.lang.String"> <constructor-arg index="0" value="hello matt"/> </bean> <bean id="hello12" class="cn.matt.spring.ioc.HelloImpl"> <property name="name" ref="bean1"/> </bean>
7、内部bean
内部bean对外部不可见,不管是否指定id或name,spring都会指定唯一的匿名标识
<bean id="hello12" class="cn.matt.spring.ioc.HelloImpl"> <property name="name"> <bean id="bean2" class="java.lang.String"> <constructor-arg index="0" value="hello matt"/> </bean> </property> </bean>
8、注入null值
<bean id="hello13" class="cn.matt.spring.ioc.HelloImpl"> <property name="name"><null /></property> </bean>
五、其他配置
1、 延迟加载
<bean id="hello" class="cn.matt.HelloImpl" lazy-init="true"/>
2、init 与 destroy 方法
<bean id="hello" class="cn.matt.HelloImpl" init-method="init" destroy-method="destroy"/>
init-method="init" :指定初始化方法,在构造器注入和setter注入完毕后执行
destroy-method="destroy":指定销毁方法,只有“singleton”作用域能销毁,“prototype”作用域的一定不能
3、Bean的作用域
<!-- 单例 --> <bean class="cn.matt.HelloImpl" scope="singleton"/> <!-- 原型 --> <bean class="cn.matt.HelloImpl" scope="prototype"/>
singleton:指“singleton”作用域的Bean只会在每个Spring IoC容器中存在一个实例,而且其完整生命周期完全由Spring容器管理。对于所有获取该Bean的操作Spring容器将只返回同一个Bean。
prototype:即原型,指每次向Spring容器请求获取Bean都返回一个全新的Bean,相对于“singleton”来说就是不缓存Bean,每次都是一个根据Bean定义创建的全新Bean。
参考:
第二章 IoC 之 2.1 IoC基础 ——跟我学Spring3
第二章 IoC 之 2.2 IoC 容器基本原理 ——跟我学Spring3
第二章 IoC 之 2.3 IoC的配置使用——跟我学Spring3
第三章 DI 之 3.1 DI的配置使用 ——跟我学spring3
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析