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”)标注才会使多例
registerBeanDefinition
getMergedBeanDefinition
resolveBeforeInstantiation
createBeanInstance
populateBean
populateBean
initializeBean
initializeBean
initializeBean
initializeBean
preInstantiateSingletons
destroyBean
destroyBean
AOP(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。