一、spring核心
控制反转IOC
控制反转(Inversion of Control,简称IoC)是面向对象编程中的一种设计原则,它主要用于管理和解耦组件之间的依赖关系。IoC的核心思想是将组件的控制权从组件本身转移到外部容器或框架,以达到解耦的效果。以下是对IoC的详细解析:
1. IoC的基本概念
- 定义:IoC是一种设计原则,它指的是将组件的控制权从组件本身转移到外部容器。在传统的面向对象编程中,组件通常需要自己管理和创建依赖对象,而IoC则是由容器来负责创建和管理组件之间的依赖关系。
- 目的:通过IoC,组件之间的依赖关系被解耦,使得组件更加独立和可复用。组件不再依赖具体的实现类,而是依赖接口或抽象类,从而方便替换和扩展。
2. IoC的实现方式
- 依赖注入(Dependency Injection,简称DI):IoC最常见的实现方式是依赖注入。在DI中,容器负责创建组件所需的依赖对象,并在组件创建时将这些依赖对象注入到组件中。这样,组件就不需要自己创建和管理依赖对象了。
- 依赖查找(Dependency Lookup):除了依赖注入外,还有一种较少使用的实现方式叫依赖查找。在这种方式中,组件会主动向容器请求所需的依赖对象。不过,这种方式通常被认为不如依赖注入灵活和强大。
3. IoC的优点
- 降低耦合度:通过将依赖关系的控制权交给外部容器,组件之间的耦合度降低,使得组件更容易测试、维护和替换。
- 提高可测试性:IoC使得依赖关系更容易模拟和替代,从而提高了单元测试和集成测试的可行性。
- 提高可扩展性:由于组件之间的依赖关系被解耦,新的组件可以更容易地添加到应用程序中,而不需要修改现有的代码。
- 提高可维护性:通过集中管理依赖关系,应用程序的配置更容易维护,使得应用程序更具可维护性。
依赖注入(Dependency Injection,简称DI)
是一种实现控制反转(IoC)的具体方式,它通过将对象所需的依赖项在创建时注入到对象中,从而实现了对象之间的解耦。依赖注入的具体实现方式主要有以下几种:
1. 构造函数注入(Constructor Injection)
-
实现方式:在类的构造函数中定义需要注入的依赖项作为参数,并在创建类的实例时将依赖项传递给构造函数。
-
优点:确保了依赖项在对象创建时就已被注入,从而避免了对象在后续使用中因依赖项未初始化而导致的错误。
-
示例:
public class UserService {
private final UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(User user) {
userDao.addUser(user);
}
}
2. Setter方法注入(Setter Injection)
-
实现方式:在类中定义setter方法,用于在对象创建后注入依赖项。
-
优点:提供了更大的灵活性,允许在对象创建后动态地更改依赖项。
-
示例:
public class UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void addUser(User user) { userDao.addUser(user); } }
3. 接口注入(Interface Injection,一般不推荐)
- 实现方式:通过对象实现的接口来注入依赖项。这种方式通常不直接用于依赖注入的实现,而是作为一种理论上的可能性。在实际应用中,接口更多地被用作定义规范和契约,而依赖注入则是通过具体的实现(如构造函数注入或Setter方法注入)来完成的。
- 注意:虽然接口注入在理论上是可行的,但在实践中并不常见,因为它需要额外的架构支持,如服务定位器(Service Locator)模式,这可能会引入额外的复杂性和潜在的耦合问题。
4. 自动装配(Autowiring)
-
实现方式:在某些框架(如Spring)中,支持自动装配功能,即框架会自动识别和解析Bean之间的依赖关系,并将相应的依赖注入到目标Bean中。自动装配可以根据不同的规则进行,如按类型、按名称、按注解等。
-
优点:简化了配置和代码的编写,提高了开发效率。
-
示例(以Spring为例):
@Component public class UserService { @Autowired private UserDao userDao; public void addUser(User user) { userDao.addUser(user); } }
面向切面编程AOP
AOP(Aspect-Oriented Programming)即面向切面编程,是一种编程范式,旨在通过横向切割业务逻辑来增强应用程序的模块性、可维护性和复用性。AOP通过将横切关注点(Cross-cutting Concerns)从主要业务逻辑中分离出来,并模块化地封装为切面(Aspect),从而在需要的地方将这些横切关注点织入到应用程序中。
AOP的七个专业术语:
(1)目标对象(Target):我们需要对他进行操作的业务类。
(2)连接点(Joinpoint):连接点就是程序执行的某个特定的位置。
(3)切点(Pointcut):一个项目中有很多的类,一个类有很多个连接点,当我们需要在某个方法前插入一段增强(advice)代码时,我们就需要使用切点信息来确定,要在哪些连接点上添加增强。
(4)增强(也有叫通知的)(Advice):AOP(切面编程)是用来给某一类特殊的连接点,添加一些特殊的功能,那么我们添加的功能也就是增强:
前置通知 (前置增强) — before() 执⾏⽅法前通知
返回通知(返回增强) — afterReturn ⽅法正常结束返回后的通知
异常抛出通知(异常抛出增强) — afetrThrow()
最终通知 — after ⽆论⽅法是否发⽣异常,均会执⾏该通知。
环绕通知 — around 包围⼀个连接点( join point )的通知
(5)切面(Aspect):是通知和切点的结合,通知和切点共同定义了切面的全部内容
(6)织入(Weaving):织入就是将增强添加到目标类具体连接点上的过程
(7)AOP代理(AOP proxy):一个类被AOP织入后生成出了一个结果类,它是融合了原类和增强逻辑的代理类