Spring-IOC
大约 4 分钟
What's IOC?
相关信息
IOC 是一个对象工厂,本质就是一个哈希表,Spring 自动生成的对象会存放在 IOC 容器中,如果需要直接从 IOC 容器中获取,无需在程序中通过 new 对象,解决类之间耦合问题。
注入容器
注解注入
以下四个注解功能完全相同,都用来标记一个类,将其注入 IOC 容器,作用是标识 MVC 分层结构,注入容器实际上会创建一个实例,默认是调用类的无参构造方法(利用其初始化属性)。
@Respository
:标记 DAO 层组件。@Service
:标记 Service 层组件@Component
:标记不确定层次的组件。@Controller
:标记 Controller 层组件。
通过参数指定 id 名,如:@Component("name")
,如果没有指定 id,默认使用类名首字母小写作为 id.
注意
不要忘记在 Application 启动类上使用注解 @ComponentScan
配置注解自动扫描包路径,只有 Spring 扫描到注解才会生效。
配置文件注入
通过 Spring 主配置文件,配置注入的 Bean 实例,给属性注入值时默认是通过调用其 set 方法。
<?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.xsd">
<!-- bean 标签:用于配置一个注入 IOC 容器的实例
id:bean 的唯一标识
class:类的限定性类名
scope:配置 bean 的范围
-->
<bean id="student" class="com.lingyuan.model.Student" scope="singleton" >
<!-- 注入属性值 -->
<property name="age"><value>18</value></property>
<property name="name">
<!-- 有左括号需要转义 -->
<value><![CDATA[<张三>]]></value>
</property>
<!-- 声明调用有参构造方法 -->
<!-- 一个标签表示带有一个构造方法参数 -->
<constructor-arg name="name" value="李四"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
<constructor-arg name="id" value="2"></constructor-arg>
</bean>
<bean id="teacher" class="com.lingyuan.model.Teacher">
<!-- 给对象类型注入值:引用 IOC 容器中已存在的一个对象-->
<property name="student" ref="student"></property>
<!-- 给对象类型注入值:内置 bean 标签,此内部 bean 无法通过 id 或类型获取,也无需id属性 -->
<property name="student">
<bean class="com.lingyuan.model.Student">
<property name="name" value="lee"></property>
<property name="age" value="18"></property>
</bean>
</property>
<!--给 List 类型注入值-->
<property name="studentList">
<list>
<!-- 引用 bean -->
<ref bean="stu"></ref>
<!-- 内置 bean -->
<bean class="com.lingyuan.model.Student">
<property name="name" value="lee"></property>
</bean>
</list>
</property>
<!--给 Map 类型注入值-->
<property name="studentMap">
<map>
<!-- 引用 bean -->
<entry key="张三" value-ref="student"></entry>
<!-- 内置 bean -->
<entry key="李四">
<bean class="com.lingyuan.model.Student">
<property name="name" value="李四"></property>
</bean>
</entry>
</map>
</property>
<!-- 给 Date 类型注入值 -->
<property name="hireDate">
<!-- 引用日期解析 bean -->
<bean factory-bean="dateFormat" factory-method="parse">
<constructor-arg value="2021-09-13"></constructor-arg>
</bean>
</property>
</bean>
<!-- 配置日期解析 bean -->
<bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg name="pattern" value="yyyy-MM-dd"></constructor-arg>
</bean>
</beans>
Bean范围
IOC 容器创建的对象默认为单例对象,配置 Bean 时通过 scope 属性改变,或通过使用 @Scope("")
标记类。
scope 属性取值:
- singleton:默认,每个 IOC 容器仅单个对象实例。
- prototype:定义为任意数量的对象实例。
- request:限定为单个 HTTP 请求的生命周期,每个 HTTP 请求都有自己的 Bean 实例,仅在 Web 感知的 Spring ApplicationContext上下文中有效。
- session:限定为 HTTP Session的生命周期。
- application:限定为 ServletContext 的生命周期。
- websocket:限定为 WebSocket 的生命周期。
获取Bean
@Autowired
/**
* 只能在 IOC 容器中的类能使用自动装配
*/
@Component
public class HelloSpring {
/**
* 属性注入,根据类型去 IOC 容器中寻找 Bean 实例装配
* @Qualifier 指定注入的 Bean id,如果容器中有多个相同类型的 bean 时使用,搭配 @Autowired 使用,非必须
*/
@Autowired
@Qualifier("student")
private Student student;
private Teacher teacher;
/**
* 构造方法注入(建议)
*/
@Autowired
public HelloSpring(Teacher teacher) {
this.teacher = teacher;
}
}
ApplicationContext
从 ApplicationContext 应用上下文中读取配置文件,获取 Bean 实例。
import com.java.pojo.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
// classpath: 指 src 目录
ApplicationContext app = new ClassPathXmlApplicationContext("classpath:springIOC.xml");
Student stu = (Student) app.getBean("student");
stu.setId(1);stu.setAge(18);stu.setName("lee");
System.out.println(stu);
}
}
配置注解扫描
注解开启
在 Spring 启动类上添加注解:
@ComponentScan(value = "com.ly")
@MapperScan(basePackages = {"com.ly.mapper"})
配置文件开启
在 Spring 主配置文件中配置注解扫描。
<?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-4.1.xsd">
<!-- 导入 context 命名空间,开启自动扫描 -->
<context:component-scan base-package="com.ly"></context:component-scan>
</beans>