Spring IoC快速入门
本文章参考于:https://www.bilibili.com/video/BV1vh411o7hc?p=107
IOC/DI-控制反转和依赖注入
IoC全称为Inverse of Control,控制反转的意思,这是一种思想,能解决代码耦合问题。
将对象实例化的创建过程转交给外部容器(IOC容器 充当工厂角色)去负责;属性赋值的操作;
例如类A要使用类B,类B是类A的属性,如果直接在类A中创建类B,当类B因业务需要修改时,也需要修改类A的代码,这种写法就是代码耦合,也可以说类A和类B属于代码耦合。
假如我们把类B的创建交给Spring,Spring通过配置文件或者通过Java注解来创建类B,然后再由Spring把创建的类B实例和类A的实例组配起来,这样就避免了类A与类B的代码耦合。这种机制就是Spring框架的控制反转思想,相当于类A把创建类B权利交给了Spring,由Spring来控制类B的创建。
Spring 框架环境搭建
添加 Spring 框架的依赖坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.4.RELEASE</version>
</dependency>
编写 Bean 对象
package org.example.service;
public class UserService {
public void test(){
System.out.println("UserService Test....");
}
}
添加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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--id:bena标签的唯一标识,一般是对应的JavaBean对象名称的首字母小写
class:JavaBean对象的类路径(包名+类名)-->
<bean id="userService" class="org.example.service.UserService">
</bean>
</beans>
加载配置文件,获取实例化对象
public class Starter01 {
public static void main(String[] args) {
//得到Spring的上下文环境
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
//通过id属性值得到指定的bean对象
UserService userService = (UserService) ac.getBean("userService");
//调用实例化好的JavaBean对象中的方法
userService.test();
}
}
Spring IOC 注入
Spring IOC 手动装配(注入)
Spring 支持的注入方式共有四种:set 注入、构造器注入、静态工厂注入、实例化工厂注入。
set方法注入
注:属性字段需要提供set方法,四种方式,推荐使用set方法注入。
业务对象 JavaBean
- 属性字段提供set方法
public class UserService {
//手动实例化
//private UserDao userDao = new UserDao();
/*
set方法注入
1、属性字段提供set方法
2、在配置文件中通过property属性指定属性字段
*/
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void test(){
System.out.println("UserService Test...");
userDao.test();
}
}
- 配置文件的bean标签设置property标签
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
Set方法注入
-->
<bean id="userService" class="org.example.service.UserService">
<!--IOC通过property标签手动装配(注入):
name:bean对象中属性字段的名称
ref:指定bean标签的id属性值 -->
<property name="userDao" ref="userDao"></property>
</bean>
<bean id="userDao" class="org.example.dao.UserDao"></bean>
</beans>
构造器注入
注:提供带参构造器,单个Bean对象作为参数(可多个Bean对象作为参数)
public class UserService02 {
private UserDao02 userDao02;
public UserService02(UserDao02 userDao02) {
this.userDao02 = userDao02;
}
public void test(){
System.out.println("UserService02 Test...");
userDao02.test();
}
}
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--构造器注入 -->
<bean id="userService02" class="org.example.service.UserService02">
<!--IOC通过构造器注入:
通过constructor-arg标签进行注入
name:属性名称
ref:指定bean标签的id属性值
-->
<constructor-arg name="userDao02" ref="userDao02"></constructor-arg>
</bean>
<bean id="userDao02" class="org.example.dao.UserDao02"></bean>
</beans>
Spring IOC 自动装配(注入)(不需要在bean标签注入依赖)
注解方式注入 Bean
对于 bean 的注入,除了使用 xml 配置以外,可以使用注解配置。注解的配置,可以简化配置文件,提高开发的速度,使程序看上去更简洁。对于注解的解释,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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--开启自动化装配(注入)-->
<context:annotation-config/>
<bean id="userService" class="org.example.service.UserService"></bean>
<bean id="userDao" class="org.example.dao.UserDao"></bean>
</beans>
2.给注入的bean对象添加注解
/*
@Resource注解实现自动注入
1、注解默认通过属性字段名称查找对应的Bean对象(属性字段名称与bean标签的id属性值一致)
@Resource
private UserDao userDao; // 属性字段的名称与bean标签的id属性值相等
2、如果属性字段名不一样,则通过类型(class)查找
@Resource
private UserDao ud; // 当在配置文件中属性字段名(ud)未找到,则会查找对应的class(UserDao类
型)
3、属性字段可以提供set方法,也可以不提供
4、注解可以声明在属性字段上或set方法上
5、可以设置注解的name属性,name属性值要与bean标签的id属性值一样
@Resource(name = "userDao") // name属性值与配置文件中bean标签的id属性值一致
private UserDao ud;
6、当注入接口时,如果接口只有一个实现类,则正常实例化;如果接口有多个实现类,则需要使用name属性指定需要被实例化的bean对象
*/
public class UserService {
@Resource
private UserDao userDao;
// public void setUserDao(UserDao userDao) {
// this.userDao = userDao;
// }
public void test(){
System.out.println("UserService Test...");
userDao.test();
}
}
Spring IOC 扫描器(不需要在配置文件配置bean标签)
实际的开发中,bean的数量非常多,采用手动配置bean的方式已无法满足生产需要,Spring这时候同样提供了扫描的方式,对扫描到的bean对象统一进行管理,简化开发配置,提高开发效率。
Spring IOC 扫描器的配置
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--
Spring IOC扫描器
作用:bean对象的统一管理,简化开发配置,提高开发效率
1、设置自动化扫描范围
2、在需要被实例化的JavaBean的类上添加指定的注解(注解声明在类级别)(bean对象的id属性默认时类的首字母小写)
Dao层:
@Repository
Service层:
@Service
Controller层:
@Controller
任意类:
@Component
注:开发过程中建议按照规则声明注解
-->
<!--设置自动化扫描范围-->
<context:component-scan base-package="org.example"></context:component-scan>
</beans>
使用特定的注解
@Repository (Dao层)
@Repository
public class TypeDao {
public void test(){
System.out.println("TypeDao Test...");
}
}
@Service(Service层 )
@Service
public class TypeService {
@Resource
private TypeDao typeDao;
public void test(){
System.out.println("TypeService Test...");
typeDao.test();
}
}
@Controller (Controller 层 )
@Controller
public class TypeController {
@Resource
private TypeService typeService;
public void test(){
System.out.println("TypeController Test...");
typeService.test();
}
}