Spring应用之了解IOC(1)
IOC(DI)-控制反转(依赖注入)
IOC称之为控制反转,简单来说就是将对象的创建的权利和对象的声明周期的管理过程交给Spring框架来处理,在这个开发过程中不再需要关注对象的创建和生命周期的管理,而是在需要的时由Spring框架提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转。
其中,在创建对象的过程中spring可以根据配置对象的属性进行设置,这个过程称为依赖注入(DI).
Spring配置的可选方案
Spring具有非常大的灵活性,它提供了三种主要的装配机制:
1.在XML中进行显式配置。
2.在Java中进行显式配置。
3.隐式的bean发现机制和自动装配。
Spring有多种可选方案来配置bean,但有时候可以在其中做出选择。Spring的配置风格是可以互相搭配的,所以你可以选择使用XML装配一些bean,使用Spring基于Java的配置(JavaConfig)来装配另一些bean,而将剩余的bean让Spring去自动发现。
自动化装配bean
Spring从两个角度来实现自动化装配:
组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
自动装配(autowiring):Spring自动满足bean之间的依赖。
组件扫描和自动装配组合在一起就能发挥出强大的威力,它们能够将你的显式配置降低到最少。
自动装配bean案例
下面将展示一个案例来Spring怎么自动装配bean。
准备
在 IDEA 工具新建一个maven project。
其maven依赖为:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.1.7.RELEASE</spring.version>
<junit.version>4.12</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
Java Bean
首先建立一个User接口。作为接口,它定义了User所能进行的操作。它将User的任意实现与User本身的耦合降低到了最小的程度。
UserService.java
package com.easy.spring.ioc.simple;
public interface UserService {
void say();
}
创建其中的一个实现,也就是UserServiceImpl类。在UserServiceImpl类上使用了@Component注解,该注解表明该类会作为组件类,并告知Spring要为这个类创建bean。
UserServiceImpl.java
package com.easy.spring.ioc.simple;
import org.springframework.stereotype.Component;
@Component
public class UserServiceImpl implements UserService {
@Override
public void say() {
System.out.println("hello world! timestamps is " + System.currentTimeMillis());
}
}
不过,组件扫描默认是不启用的。我们还需要显式配置一下Spring,从而命令它去寻找带有@Component注解的类,并为其创建bean。SpringAppConfig配置类展现了完成这项任务的最简洁配置。如果没有其他配置的话,@ComponentScan默认会扫描与配置类相同的包,因此Spring将会扫描这个包以及这个包下的所有子包,查找带有@Component注解的类。这样的话,就能发现UserServiceImpl,并且会在Spring中自动为其创建一个bean。
SpringAppConfig.java
package com.easy.spring.ioc.simple;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class SpringAppConfig {
}
创建一个简单的JUnit测试,它使用了Spring的SpringJUnit4ClassRunner,这时会创建Spring上下文,注解@ContextConfiguration会告诉它需要在SpringAppConfig中加载配置。因为SpringAppConfig类中包含了@ComponentScan,则在最终的上下文中会创建UserServiceImpl 类。
package com.easy.spring.ioc.simple;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.Assert.assertNotNull;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringAppConfig.class)
public class AppTest {
@Autowired
private UserService userService;
@Test
public void test() {
assertNotNull(userService);
userService.say();
}
}
其运行结果:
hello world! timestamps is 1564324423904
参考: 《Spring实战》