Spring 是一款开源的轻量级 Java 开发框架,它使创建 Java 企业应用程序变得容易。它提供了在企业环境中使用 Java 语言所需的一切,并可以根据应用程序的需求灵活地创建多种架构。
Spring 提供的核心功能主要是 IoC 和 AOP
IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。
为什么叫控制反转?
| 作用域 | 说明 | 
|---|---|
| singleton | 默认 Spring Bean 作用域,一个 BeanFactory 有且仅有一个实例 | 
| prototype | 原型作用域,每次依赖查找和依赖注入生成新 Bean 对象 | 
| request | 将 Spring Bean 存储在 ServletRequest 上下文中 | 
| session | 将 Spring Bean 存储在 HttpSession 中 | 
| application | 将 Spring Bean 存储在 ServletContext 中 | 
@Autowired 是 Spring 提供的注解,@Resource 是 JDK 提供的注解。
Autowired 默认的注入方式为byType(根据类型进行匹配),@Resource默认注入方式为 byName(根据名称进行匹配)。
当一个接口存在多个实现类的情况下,@Autowired 和@Resource都需要通过名称才能正确匹配到对应的 Bean。Autowired 可以通过 @Qualifier 注解来显式指定名称,@Resource可以通过 name 属性来显式指定名称。
Spring 框架中的 Bean 是否线程安全,取决于其作用域和状态。
大部分 Bean 实际都是无状态(没有定义可变的成员变量)的(比如 Dao、Service),这种情况下, Bean 是线程安全的。
对于有状态单例 Bean 的线程安全问题,常见的有两种解决办法:
ThreadLocal 成员变量,将需要的可变成员变量保存在 ThreadLocal 中(推荐的一种方式)。@SpringBootApplication,这个注解是对三个注解进行了封装:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
其中@EnableAutoConfiguration是实现自动化配置的核心注解。@Import注解导入AutoConfigurationImportSelector,这个类实现了一个导入器接口ImportSelector。在该接口中存在一个方法selectImports,spring容器中的类的全类名。在AutoConfigurationImportSelector类中重写了这个方法,classpath路径下META-INF/spring.factories文件中的所配置的类的全类名。Bean会根据条件注解所指定的条件来决定是否需要将其导入到Spring容器中。@AutoConfigurationPackage和@ComponentScan一样,都是将Spring Boot启动类所在的包及其子包里面的组件扫描到IOC容器中,但是区别是@AutoConfigurationPackage扫描@Enitity、@Mapper等第三方依赖的注解,@ComponentScan只扫描@Controller/@Service/@Component/@Repository这些常见注解。所以这两个注解扫描的对象是不一样的。当然这只是直观上的区别,更深层次说,@AutoConfigurationPackage是自动配置的提醒,是Spring Boot中注解,而@ComponentScan是Spring的注解
@Import注解导入AutoConfigurationImportSelector,这个类实现了一个导入器接口ImportSelector。在该接口中存在一个方法selectImports,默认都是单例对象,就算对象标注@Scope(value = “prototype”)也无法生效
特殊情况是多例对象,当注入方和被注入方都被@Scope(value = “prototype”)标注才会使多例
registerBeanDefinitiongetMergedBeanDefinitionresolveBeforeInstantiationcreateBeanInstancepopulateBeanpopulateBeaninitializeBeaninitializeBeaninitializeBeaninitializeBeanpreInstantiateSingletonsdestroyBeandestroyBeanAOP(Aspect-Oriented Programming:面向切面编程)
AOP 切面编程设计到的一些专业术语:
| 术语 | 含义 | 
|---|---|
| 目标(Target) | 被通知的对象 | 
| 代理(Proxy) | 向目标对象应用通知之后创建的代理对象 | 
| 连接点(JoinPoint) | 目标对象的所属类中,定义的所有方法均为连接点 | 
| 切入点(Pointcut) | 被切面拦截 / 增强的连接点(切入点一定是连接点,连接点不一定是切入点) | 
| 通知(Advice) | 增强的逻辑 / 代码,也即拦截到目标对象的连接点之后要做的事情 | 
| 切面(Aspect) | 切入点(Pointcut)+通知(Advice) | 
| Weaving(织入) | 将通知应用到目标对象,进而生成代理对象的过程动作 | 
一个advice就是一个方法,即目标对象必须要执行的完成的工作。
因为spring aop只能代理目标方法,所有advice就会被解析成MethodAdvice。
这里以BeforeAdvice举例。
MethodBeforeAdvice,但只有这个类还不够,因为我们的方法还无法继续往下执行,需要将MethodBeforeAdvice转化为methodInterceptor。它封装了MethodBeforeAdvice,将其变成真正的增强方法,因为methodInterceptor封装了代理方法,提供了统一的逻辑。
一个advisor对应一个pointcut和一个advice。