一、IoC 与 Bean 管理基础概念
1.1 什么是 IoC(控制反转)
IoC(Inversion of Control)即 "控制反转",是 Spring 框架的核心思想。传统开发中,对象的创建与依赖关系由程序自身控制;而在 IoC 模式下,对象的创建、初始化和依赖关系的管理由 Spring 容器负责,程序只需从容器中获取所需对象,从而实现了控制权的反转。
1.2 Bean 的本质与作用
在 Spring 中,"Bean" 指的是由 Spring 容器管理的对象。这些对象经过 Spring 容器的创建、配置和管理,成为应用程序的组成部分。Bean 可以是业务对象、服务对象、数据访问对象等,Spring 通过 Bean 管理实现了组件的解耦和灵活配置。
二、基于 XML 配置的 Bean 管理实现
2.1 Bean 的基本定义与创建
在 Spring 中,通过 XML 配置文件定义 Bean 是最传统的方式。以下是一个完整的示例,展示了如何在 XML 中定义不同类型的 Bean:
<!-- Spring.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 定义基础Bean:Demo类 -->
<bean id="demo" class="com.qcby.Demo"/>
<!-- 定义Cat Bean,包含基本属性和对象引用 -->
<bean id="cat" class="com.qcby.Cat">
<property name="age" value="10"/>
<property name="color" value="white"/>
<property name="name" value="xiaohua"/>
<property name="weight" value="888"/>
<property name="demo" ref="demo"/>
</bean>
<!-- 定义Dog Bean,包含复杂类型属性 -->
<bean id="dog" class="com.qcby.Dog">
<property name="arr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
<property name="list">
<list>
<value>aassa</value>
<value>aassa</value>
<value>aassa</value>
<value>aassa</value>
</list>
</property>
<property name="map">
<map>
<entry key="aaa" value="aasaas"/>
<entry key="aaa1" value="aasaas1"/>
<entry key="aaa2" value="aasaas2"/>
<entry key="aaa3" value="aasaas3"/>
</map>
</property>
</bean>
<!-- 定义User Bean,通过构造函数注入 -->
<bean id="user" class="com.qcby.User">
<constructor-arg name="age" value="18"/>
<constructor-arg name="name" value="aa"/>
<constructor-arg name="demo" ref="demo"/>
</bean>
</beans>
2.2 属性注入的三种方式
2.2.1 基本属性注入
通过<property>
标签的name
和value
属性实现基本类型属性的注入:
<property name="age" value="10"/>
<property name="name" value="xiaohua"/>
2.2.2 对象引用注入
通过ref
属性引用其他 Bean,实现对象依赖关系的注入:
<property name="demo" ref="demo"/>
2.2.3 复杂类型注入
- 数组注入:使用
<array>
标签
<property name="arr">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
</array>
</property>
- 集合注入:使用
<list>
标签
<property name="list">
<list>
<value>aassa</value>
<value>aassa</value>
</list>
</property>
- Map 注入:使用
<map>
和<entry>
标签
<property name="map">
<map>
<entry key="aaa" value="aasaas"/>
<entry key="aaa1" value="aasaas1"/>
</map>
</property>
2.2.4 构造函数注入
通过<constructor-arg>
标签按参数名或索引注入构造函数参数:
<bean id="user" class="com.qcby.User">
<constructor-arg name="age" value="18"/>
<constructor-arg name="name" value="aa"/>
<constructor-arg name="demo" ref="demo"/>
</bean>
三、基于注解的 Bean 管理实现
3.1 注解类型与作用
Spring 提供了一系列注解用于 Bean 的定义和管理,主要包括:
组件扫描注解:
@Component
:通用组件注解,标识一个受 Spring 管理的 Bean@Controller
:标识 Web 层控制器 Bean@Service
:标识服务层 Bean@Repository
:标识数据访问层 Bean
依赖注入注解:
@Autowired
:按类型自动装配@Qualifier
:配合@Autowired
按名称装配@Value
:注入基本类型属性值
3.2 注解实现示例
以下是使用注解定义 Bean 的代码示例:
// Demo.java - 使用@Component注解定义Bean
package com.qcby;
import org.springframework.stereotype.Component;
@Component
public class Demo {
public void hello(){
System.out.println("hello");
}
}
// Cat.java - 使用@Controller注解定义Bean
package com.qcby;
import org.springframework.stereotype.Controller;
@Controller
public class Cat {
private int age;
private String name;
private String color;
private int weight;
// 通过@Autowired注入Demo Bean
@Autowired
private Demo demo;
// 省略getter/setter方法
@Override
public String toString() {
return "Cat{" +
"age=" + age +
", name='" + name + '\'' +
", color='" + color + '\'' +
", weight=" + weight +
", demo=" + demo +
'}';
}
public void eat(){
System.out.println("Cat eats fish");
}
}
// Dog.java - 使用@Repository注解定义Bean
package com.qcby;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Repository
public class Dog {
private int[] arr;
private List<String> list;
private Map<String,String> map;
// 省略getter/setter方法
@Override
public String toString() {
return "Dog{" +
"arr=" + Arrays.toString(arr) +
", list=" + list +
", map=" + map +
'}';
}
public void jump(){
System.out.println("jump.....");
}
}
3.3 启用注解扫描
要使注解生效,需在 XML 配置中添加组件扫描配置:
<!-- 启用组件扫描,扫描com.qcby包下的所有注解Bean -->
<context:component-scan base-package="com.qcby"/>
四、实战测试
以下是使用 Spring 容器获取 Bean 并验证功能的测试代码:
// UserTest.java - 测试Spring Bean管理功能
package com.qcby;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserTest {
/**
* 传统方式创建对象
*/
@Test
public void run(){
Demo demo = new Demo();
demo.hello();
}
/**
* 通过Spring IoC容器获取Bean(XML方式)
*/
@Test
public void run1(){
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
Demo demo = (Demo) context.getBean("demo");
demo.hello();
}
/**
* 获取Dog Bean并验证复杂类型注入
*/
@Test
public void run2(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Dog dog = (Dog)context.getBean("dog");
System.out.println(dog.toString());
}
/**
* 获取Cat Bean并验证属性注入
*/
@Test
public void run3(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
Cat cat = (Cat)context.getBean("cat");
System.out.println(cat.toString());
}
/**
* 获取User Bean并验证构造函数注入
*/
@Test
public void run4(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
User user = (User)context.getBean("user");
System.out.println(user.toString());
}
}
测试结果: