1、定义
在软件开发中,分层解耦是一种设计原则,旨在将应用程序划分为不同的逻辑层次,使每个层次的功能和责任清晰,从而降低系统的耦合性,提高代码的可维护性、可扩展性和可重用性。分层解耦有助于将复杂的系统拆分为独立的模块,使各个模块之间的关系更加明确,便于团队协作和系统维护。
通常会将其分为三层,也称三层架构:
controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
service: 业务逻辑层,处理具体的业务逻辑。
dao:数据访问层(Data Access object)(持久层),负责数据访问操作,包括数据的增、删、改、查。
注:按需求通过定义接口方法来灵活实现功能
2、如何实现解耦
在spring框架中,有三个核心概念用于实现解耦,分别是控制反转、Bean对象以及依赖注入。它们帮助实现松耦合、模块化、可维护和可扩展的应用程序。
-
控制反转(Inversion of Control,IoC):
- 控制反转是Spring框架的基础概念之一,它指的是将对象的创建和管理权从应用程序代码转移到外部容器(Spring容器)中。
- 在传统的应用程序中,对象的创建通常由应用程序代码直接完成,而在IoC中,这些对象的创建和生命周期管理由IoC容器负责。
- IoC容器负责管理应用程序中的各个对象,根据配置和需要创建、组装和销毁这些对象,从而实现了对象的解耦和灵活性。
-
Bean对象:
- 在Spring框架中,Bean是一个用于表示由Spring容器管理的对象的术语。
- Bean可以是任何的Java对象,包括POJO(Plain Old Java Object)和Spring特定的组件。
- 在配置文件或注解中,可以定义Bean的属性、依赖关系和其他配置信息。
-
依赖注入(Dependency Injection,DI):
- 依赖注入是IoC的一个关键实现方式,它是通过将对象的依赖关系注入到对象中,而不是在对象内部直接创建依赖关系。
- 通过DI,对象不需要自己创建或查找它所依赖的其他对象,而是由容器在创建对象时自动将依赖关系注入进去。
- DI减少了对象间的直接耦合,使得代码更加可维护、可测试和可扩展。
注意:虽然此处控制反转和依赖注入分开讨论,但他们其实关系紧密,因为控制反转强调的是将对象的控制权(包括创建和管理)从应用程序代码转移到外部容器(如Spring容器)中。这是一种理论做法。而依赖注入则是实现IoC的一种具体方式,它通过将对象所依赖的其他对象注入到对象内部,实现了依赖关系的解耦。
3、如何具体操作
1)如何声明bean对象
使用注解:
- 在类上使用
@Component
、@Service
、@Repository
、@Controller
等注解来声明Bean对象。这些注解都是@Component
注解的扩展,用于标识不同类型的组件。 - 在Spring容器启动时,它会扫描带有这些注解的类,并将它们实例化为Bean对象。
- 适用于声明具有特定用途的Bean,如服务类、控制器等。
注解
说明
位置
@Component
声明bean的基础注解
不属于以下三类,用此注解
@Controller
@Component的衍生注解
标注在控制器类上
@Service
@Component的衍生注解
标注在业务类上
@Repository
@Component的衍生注解
标注在数据访问类上(由于与mybatis整合,用的少)
注意事项
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
使用Java配置类:
- 创建一个带有
@Configuration
注解的Java类,然后在该类中使用@Bean
注解来声明需要被容器管理的Bean对象。 - 在Java配置类中,通过方法返回一个对象,并将其标记为Bean,Spring容器会根据这些定义来创建和管理Bean对象。
- 适用于声明自定义的Bean,并对其进行更精确的配置。
使用XML配置:
- 在XML配置文件中使用
<bean>
元素来声明Bean对象。 - 通过指定类名、属性值和依赖关系,可以在XML中定义Bean的实例化和配置信息。
2)如何实现依赖注入
构造函数注入(Constructor Injection):
- 在类的构造函数中声明依赖项,并通过构造函数来注入。
- Spring容器会在实例化类时自动将所需的依赖项传递给构造函数。
例:
@Component
public class MyService {
private final MyDependency dependency;
@Autowired
public MyService(MyDependency dependency) {
this.dependency = dependency;
}
}
属性注入(Property Injection):
- 在类的属性上使用注解(如
@Autowired
)声明依赖项。 - Spring容器会自动将依赖项注入到这些属性中。
- 通常使用属性注入时,需要确保依赖项不是null,可以通过添加
@Autowired(required = true)
来实现。
例:
方法注入(Method Injection):
- 在类的方法上使用注解(如
@Autowired
)声明依赖项。 - Spring容器会在对象创建后调用这些方法,并注入依赖项。
- 适用于需要在对象创建后进行一些初始化操作的情况。
例:
@Component
public class MyService {
private MyDependency dependency;
@Autowired
public void setDependency(MyDependency dependency) {
this.dependency = dependency;
}
}