1. 基本概念
(1)轻量级的JavaEE开发框架
(2)Spring的两个特性
- IOC:控制反转,将创建对象的过程交给Spring进行管理
- AOP:面向切面,不修改源代码的情况加进行功能增强
2. IOC容器
控制反转:从主动创建对象变为被动接受对象(例如使用setter方式创建)
IOC是一个容器,帮我们管理所有的组件。
容器启动的时候创建所有单实例对象。
我们可以从直接从容器中获取到这个对象。
DI是实现IOC的一种方法。
Question 1:IOC容器的启动过程?启动期间都做了什么?
// 构造器ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc.xml"); // 构造器
1
2
3
4
5
6
7
2. 执行refresh()
3.
4. ```java
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 解析xml文件finishBeanFactoryInitialization(beanFactory); // 初始化bean //调用了↓进行初始化 beanFactory.preInstantiateSingletons();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
6. ```java
// 获取需要创建的单实例对象
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 获取代创建bean的类信息
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 创建非抽象单实例对象
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()){
// 创建对象
getBean(xx);
}
// 创建好的对象最终保存在map中
- Question 2:IOC是如何创建并管理单实例bean的?保存到了哪里?
2.1 IOC概念和原理
2.1.1 基本概念
什么是IOC
(1) 控制反转:把对象创建和对象之间的调用过程交给Spring进行管理
(2) 使用IOC的目的:降低耦合度
- 控制:资源的获取方式
- 主动式:使用new方式创建资源,复杂对象的创建过于繁琐、麻烦。
- 被动式:资源的创建过程由容器来创建和设置,我们直接使用资源即可。
- 容器:管理所有的组件(有功能的类)。
- 反转:将资源创建的过程交给Spring来做。
- DI,Denpendency Injection:依赖注入,通过反射创建组件。
- 控制:资源的获取方式
2.1.2 底层原理
IOC底层原理
(1)xml解析、工厂模式、反射
2.2 IOC操作Bean管理(基于注解)
tips:使用xml管理bean,使用注解注入属性
2.2.1 使用注解创建对象
@Component:控制器,推荐给控制器层(servlet包下的组件)添加
@Service:业务逻辑,推荐个service包下的组件添加
@Repository:数据库层(持久化层、dao层)的组件添加
@Controller:不属于以上三层的组件
1 |
|
1 | <context:component-scan base-package="indi.pancras.spring5"></context:component-scan> |
1 |
|
2.2.2 使用注解注入属性
A. @Autowired
根据属性类型进行注入
原理:
- 按照类型区容器中寻找对应的组件:bookService = ioc.getBean(BookService.class);
- ① 找到一个就赋值
- ② 没找到,抛异常(或者可通过设置required=false设置为null)
- ③ 找到多个,按照变量名作为id进行匹配:bookService = ioc.getBean(“bookService”);
1 |
|
方法上有@Autowire时,方法的每一个参数都会自动注入值
B. @Qualifier
当同一个接口有两个实现类时,使用 @Qualifier
指定id进行装配
1 | // UserService.java |
C. @Resource
根据属性类型或属性名称注入
属于java拓展包里的内容,不建议使用
D. @Value
注入普通类型属性,和配置文件搭配使用
1 |
|
2.3 Bean的作用域和生命周期
- 默认单实例
1 |
|
- 通过scope属性配置作用域
1 | <!-- 单实例 --> |
2.4 Java配置类
使用@Configuration表明,等效于xml配置文件
1 |
|
3 AOP
3.1 AOP概念和原理
3.1.1 什么是AOP
- 定义:AOP(Aspect Oriented Programming):面向切面编程,指在程序运行期间,将某段代码动态的切入到**指定方法的指定位置**进行运行的编程方式。
- 场景:计算器运行计算方法的时候进行日志记录
- 直接编写在方法内部:耦合度太高,修改维护麻烦,不推荐
- 使用动态代理加入日志
- JDK动态代理缺陷:如果类没有实现任何接口,则不能创建代理。
- Spring动态代理:实现简单,无需要求被代理类实现接口
- AOP的底层:动态代理
降低模块的耦合度、添加新的功能而不修改源代码
3.1.2 AOP底层原理
使用动态代理:
- 有接口:使用JDK动态代理
- 无接口:使用CGLIB动态代理
3.1.3 专业术语
- 连接点:每一个方法的每一个可以被通知的位置
- 切入点:连接点的子类,实际被插入代码的
- 通知(增强):实际增强的逻辑
- 前置通知:方法执行前执行,@Before
- 后置通知:方法执行后执行,@After
- 环绕通知:方法执行前后执行,@Around
- 异常通知:方法出现异常时执行,@AfterThrowing
- 返回通知:方法返回后执行,@AfterReturning
- 切面:把通知应用到切入点的过程
(4) 使用场景
- AOP+日志保存到数据库中
- 权限认证
- 安全检查
- 事务控制
3.2 AOP操作
Spring框架一般基于AspectJ实现AOP操作
3.2.1 切入点表达式
- execution()
1 | // 对indi.pancras.spring5.User类里面的add()进行增强 |
3.2.2 一个示例
- bean5.xml
1 |
|
- User.java
1 |
|
- UserProxy.java
1 |
|
- test.java
1 | class UserProxyTest { |
Reference: