介绍
当谈论到软件开发和设计模式时,"IoC" 和 "DI" 是两个经常被提及的概念。它们常常会一起出现,因为它们之间有着密切的关联。
IoC(Inversion of Control)控制反转: 控制反转是一种软件设计原则,其核心思想是将某些活动的控制权从程序本身转移到框架或容器中,从而使得组件之间解耦合,降低耦合度,提高灵活性和可维护性。通俗的说,控制反转就是将原本由程序员直接调用的控制权交给容器或者框架来管理。
DI(Dependency Injection)依赖注入: 依赖注入是实现 IoC 的一种具体方式,它是指系统中的对象通过外部传递依赖(例如构造函数注入、属性注入、接口注入等)来实现对其他对象的控制权转移。通过依赖注入,对象之间的依赖关系由容器负责管理,而不是由对象自己创建或管理。
- 在Spring中,IoC和DI是通过容器来实现的。IoC容器是负责管理应用程序中各个组件(Bean)的创建、配置和生命周期的容器。通过IoC容器,应用程序不再需要直接创建和管理组件,而是将这些责任交给了容器。DI是IoC的一种实现方式,它通过将组件之间的依赖关系(依赖)从组件内部移动到容器中,来实现控制反转。通过DI,容器负责在组件初始化时将依赖注入到组件中,而不再需要组件自己去查找或创建依赖。
- 组件之间的关系通过配置文件(如XML配置文件)或注解来描述。通过配置文件或注解,可以告诉IoC容器如何创建和管理组件之间的依赖关系。Spring IoC容器会根据配置文件或注解的信息,在应用程序启动时自动创建和装配组件,并在需要时注入依赖。
共有两类注解类型可以实现:
类注解:@Controller、@Service、@Repository、@Component、@Configuration
方法注解:@Bean
类注解
1、@controller(控制器存储):使用注解就可以将该对象放在Spring容器中,控制层接收请求,对请求进行处理,并进行响应。
@Controller
public class UserController {
public void sayHi() {
System.out.println("UserController");
}
}
2、@Service(服务存储):业务逻辑层,处理具体的业务逻辑。
@Service
public class UserService {
public void doService() {
System.out.println("UserService");
}
}
3、@Repository(仓库存储):数据访问层,也称为持久层。负责数据访问操作。
@Repository
public class UserRepository {
public void doRepository() {
System.out.println("UserRepository");
}
}
4、@Configuration(配置存储):配置层,处理项目中的一些配置信息。
@Configuration
public class UserConfiguration {
public void doConfiguration() {
System.out.println("UserConfiguration");
}
}
5、 @Component(组件存储):元注解,可以注解其他类的注解,如 @Controller、@Service、@Repository 等。
@Component
public class UserComponent {
public void doComponent() {
System.out.println("UserComponent");
}
}
方法注解
在Spring框架的设计中,方法注解 @Bean 要配合类注解才能将对象正常的存储到Spring容器中。
@Component
public class BeanConfig {
@Bean
public User user() {
User user = new User();
user.setId(1);
user.setName("xiaoming");
user.setAge(18);
return user;
}
}
定义多个对象
@Component
public class BeanConfig {
@Bean
public User user() {
User user = new User();
user.setId(1);
user.setName("张三");
user.setAge(18);
return user;
}
@Bean
public User user() {
User user = new User();
user.setId(2);
user.setName("李四");
user.setAge(20);
return user;
}
}
路径扫描
Spring默认只会对启动类所在的目录下进行扫描,默认扫描的范围是启动类所在包及其子包,并且扫描的是搭配了五大注解的类或者搭配五大注解+Bean的类。如果将启动类移动之后就会报错。
这个时候可以通过 @ComponentScan 来配置路径扫描:
@ComponentScan({"com.example.spring.service"})
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
同时@ComponentScan括号里的 { } ,可以加多个大括号,表示扫描多个路径。
@ComponentScan({"com.example.spring.service"},{},{})