IOC(Inversion of Control)翻译为控制反转,是面向对象编程中的一种设计思想,可以降低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫依赖查找(Dependency Lookup,简称DL)。通过控制反转,对象在被创建的时候,由Spring容器将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
Spring实现IoC的两种方式分别是使用配置文件方式和使用注解方式,这两种方式要实现的功能是一样的,都是为了降低程序之间的耦合,只是配置的形式不一样
1. 使用配置文件(xml)的方式实现IoC
以后程序间的依赖关系都交给spring容器来管理。在某个类需要用到其他类的对象时,由spring提供该对象,我们只需要在配置文件中说明。
可以注入的数据有三类:分别为基本类型与String类型、bean类型(类类型)、复杂类型(集合类型)
可以注入的方式有三种:分别为使用构造函数注入、使用set方法注入、使用注解注入
2. 使用注解的方式实现IoC
2.1 前提条件
- 导入spring-aop-5.1.6.RELEASE.jar
- 在xml文件中导入context命名空间并配置要扫描的包
<?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">
<!--Spring容器在创建时要扫描的包-->
<context:component-scan base-package="service"></context:component-scan>
<context:component-scan base-package="dao"></context:component-scan>
</beans>
2.2 Spring中IoC的常用注解
2.2.1用于创建对象并保存到spring容器的注解(等同于在xml中编写一个<bean></bean>标签)
-
@Component(value="userService")
用于把当前类对象存入Spring容器中。value属性用于指定bean的id,当我们不写时,默认value值为当前类名且首字母小写,即@Component
等同于@Component(value="userService")
-
@Controller
和@Service
和@Repository
三个注解的作用和属性都和@Component
一模一样,是spring框架专门提供的用于三层架构层次的注解,使三层对象更加清晰。
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
public class UserService {
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
2.2.2用于注入数据的注解(等同于在xml的<bean>标签内编写一个<property>标签)
注:集合类型的数据注入只能通过xml实现
-
@Autowired
自动按照类型注入(用于类类型),如果spring容器中有唯一的一个bean对象类型与要注入的变量类型匹配,就直接注入,如果容器内有多个和变量数据类型相同的类,spring再去查找容器内相同类中是否有和该变量名称相同的bean的id,匹配上就注入,匹配不上就报错。@Autowired
注解可以写在变量上,也可以写在方法上。在使用注解方式注入时,类中的set方法就不是必须的了。@Autowired
注解有三种使用方式,分别为变量注入,构造器注入和set方法注入,它们的作用是等同的。
package service;
import dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component(value="userService")
public class UserService {
//1.变量(field)注入 --不推荐--
// @Autowired
// public UserDao UserDao = null;
//2.构造器注入
// private UserDao userDao = null;
// @Autowired
// public UserService(UserDao userDao){
// this.userDao = userDao;
// }
//3.set方法注入
private UserDao userDao;
@Autowired
public void setUserDao (UserDao userDao) {
this.userDao = userDao;
}
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
package dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
public void showDao(){
System.out.println("UserDao中的showDao方法执行了===");
}
}
-
@Qualifier
(用于类类型),在按照类型注入的基础之上再按照名称注入,在给类中的变量注入时,不能单独使用,在给方法参数注入时,可以单独使用。value属性用于指定注入bean的id。
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
public class UserService {
@Autowired
@Qualifier(value = "userDao")
public UserDao UserDao = null;
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
-
@Resource
(用于类类型),直接按照bean的id注入,可以单独使用。name属性用于指定bean的id。
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
public class UserService {
@Resource(name = "userDao")
public UserDao UserDao = null;
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
-
@Value
(用于基本数据类型和String类型),value属性用于指定数据的值,可以使用SpEL表达式。
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
public class UserService {
@Value(value = "你怎么这么好看---")
private String testString;
public String getTestString() {
return testString;
}
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
2.2.3用于改变作用范围的注解(等同于在xml的<bean>标签内编写一个<scope>标签)
-
@Scope
用于指定bean的作用范围,value属性用于指定范围的取值,常用的有两种,分别为singleton
(单例) 和prototype
(多例)
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
//@Scope("singleton")
@Scope("prototype")
public class UserService {
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
2.2.4和生命周期相关的注解(等同于在xml的<bean>标签内编写一个<init-method>和<destroy-method>标签)
-
@PostConstruct
用于指定初始化方法 -
@PerDestroy
用于指定销毁方法
package service;
import org.springframework.stereotype.Component;
@Component(value="userService")
@Scope("singleton")
public class UserService {
@PostConstruct
public void init(){
System.out.println("UserService中的init方法执行了===");
}
@PreDestroy
public void destroy(){
System.out.println("UserService中的destroy方法执行了===");
}
public void showService(){
System.out.println("UserService中的showService方法执行了===");
}
}
网友评论