spring
Posted 第二人生Bonnie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring相关的知识,希望对你有一定的参考价值。
课程主题
抽象模板设计模式&策略模式&spring核心理解&spring手写ioc模块思路分析
课程目标
1.掌握抽象模板设计模式的具体用法
2.掌握策略设计模式的具体用法
3.掌握spring和spring boot、springcloud等的关联和区别
4.搞清楚spring中的IoC、DI、AOP、BOP、基础容器、高级容器等核心概念
5.通过画图搞清楚spring是如何通过容器去创建和管理bean实例的?
6.手写spring ioc模块思路分析(V2V34)
7.掌握spring源码中的基础容器源码阅读入口
8.掌握spring源码中的高级容器源码阅读入口
spring课程安排
1 IOC、DI
手写
源码阅读
2 AOP
手写
源码阅读
spring 事务等这些偏应用的部分,都是在录播课程里面
课程回顾
1.原型设计模式
对象的new操作比较耗费资源
对象的构造比较复杂
2.单例设计模式
* 线程安全的三种懒汉式单例写法(双重检查锁、静态内部类、枚举)
* 如何破坏单例和预防单例的破坏
* 并发编程中的三大特性及如何去处理
课程内容
1.抽象模板设计模式
* 由抽象出来的父类来编写代码中不变的部分。
* 将变化的部分交给子类去完成。通过抽象方法让子类必须去完成
* 抽象模板方法是遵循了里式替换设计原则,是对继承的一种优秀的使用经验。
例子:把大象装冰箱,分三步
* 这是抽象模板方法设计模式中抽象出来的父类的描述方式
** (第一步:把冰箱门打开、第二步:把大象装进去、第三步:把冰箱门关上)
* 具体的第二步需要先把大象弄死,然后xxx,再然后xxx
代码例子:去统计代码的执行时间(第一步:计时开始 第二步:代码执行 第三步:计时结束)
见代码
2.策略模式
* 将不同的算法分别封装到不同的类当中。便于扩展和维护
* 策略模式就是让调用这些策略的使用者来讲,根本感知不到策略代码发生了扩展。
* 策略模式有两种常用的使用方式
** 一种就是你给我什么策略,我干什么事情
public interface Strategy {
public int doOperation(int num1, int num2);
}
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}
public int executeStrategy(int num1, int num2){
return strategy.doOperation(num1, num2);
}
}
** 还有一种就是我自己拥有很多策略,我会根据具体的情况去选择具体的策略
public interface TravelStrategy {
//出行方式
void travelWay();
boolean isOK(int type);
}
public class PersonContext {
// 拥有一个出行策略引用
private List<TravelStrategy> strategylist;
public PersonContext() {
this.strategylist = new ArrayList<>();
strategylist.add(new AirPlanelStrategy());
strategylist.add(new TrainStrategy());
strategylist.add(new BicycleStrategy());
}
public void travel(int juli) {
// 根据具体策略类,执行对应的出行策略
for (TravelStrategy travelStrategy : strategylist) {
if (travelStrategy.isOK(juli)) {
travelStrategy.travelWay();
break;
}
}
}
* 举个栗子:锦囊妙计(对外来说,长得都差不多)
* 策略模式其实很多时候都是可以优化if语句的。
* 举个栗子 :
将计算行为抽象出来,作为策略接口(Strategy),而这个接口下面有加法计算行为、有乘法计算行为。
* 将Mybatis中3.0版本中的NodeHandler的部分使用策略模式去改造
3.spring核心理解
* 掌握spring和spring boot、springcloud等的关联和区别
** spring.io
*** Spring基础部分(IoC、DI、AOP)
*** spring boot:更加简单
**** 自动配置
**** 起步依赖(maven依赖更加简洁)
**** 领配置文件(spring配置文件)
*** spring framework(就是我们要学习的spring,这里面包含springmvc模块)
**** 分成很多组件(jar包)
*** Spring企业应用组件
*** spring cloud
*** spring data
*** spring security
* spring立志要成为一站式轻量级企业开发框架。
* spring 核心概念
** IoC:控制反转,其实new对象的权利由使用者改为spring去创建。spring要想使用IoC去创建对象,必须使用到DI
** DI:依赖注入,就是给new出来的对象设置成员变量。
** AOP:就是将项目中的业务代码(提交订单)和系统代码(事务、记录日志)进行解耦,也是给业务代码进行功能增强的一种途径。
*** AOP是和OOP一样,都是编程思想
*** AOP的实现都有哪些呢?
**** spring aop
**** AspectJ
**** spring 整合 AspectJ
** BOP:面向Bean的编程。在spring中一切都是针对Bean设计和编程的。
*** Bean被spring通过IoC和DI进行创建和管理。
*** Bean被spring通过AOP进行功能增强。
*** Bean其实就是对应bean标签和@Bean注解的类
** 基础容器:IoC容器、【BeanFactory接口】(DefaultListableBeanFactory)
** 高级容器:【ApplicationContext接口】,实现了BeanFactory接口,只是在该接口之外,新加了一些高级功能,本质是还是一个BeanFactory。
*** 高级容器和基础容器的区别
**** 高级容器对于bean实例的加载时机是项目启动时。(饿汉式加载)
**** 基础容器对于bean实例的加载时机是第一次被需要时。(懒汉式加载)
** 循环依赖(A--->B ...... B--->A)
*** 构造方法的循环(无法解决)
public A{
private B b;
public A(B b){
this.b = b;
}
}
public B{
private A a;
public B(A a){
this.a = a;
}
}
*** set方法的循环(spring中可以通过缓存去解决掉)
public A{
private B b;
public setB(B b){
this.b = b;
}
}
public B{
private A a;
public setA(A a){
this.a = a;
}
}
* spring中使用简单工厂模式去管理bean的分析
public BeanFactory{
public Object getBean(String name){
if ("cat".equals(name)) {
return new Cat();
} else if ("dog".equals(name)) {
return new Dog();
} else if ("cow".equals(name)) {
return new Dog();
} else {
return null;
}
}
}
-------------------------------------------------
public BeanFactory{
private Map map;
public void init(){
map.put("cat",new Cat());
map.put("cow",new Cow());
}
public Object getBean(String name){
return map.get(name);
}
}
----------------------------------------------
public BeanFactory{
private Map map;
public void init(){
//读取配置文件,获取bean的信息
}
public Object getBean(String name){
return map.get(name);
}
}
<beans>
<bean id="student" class="com.kkb.spring.po.Student">
<!-- String类型 -->
<property name="name" value="james"></property>
<!-- 引用类型 -->
<property name="course" ref="course"></property>
</bean>
<!-- 该类有一个初始化方法 -->
<bean id="course" class="com.kkb.spring.po.Course"
init-method="init">
<!-- String类型 -->
<property name="name" value="spring"></property>
<!-- Integer类型 -->
<property name="age" value="18"></property>
</bean>
</beans>
4. 通过画图搞清楚spring是如何通过容器去创建和管理bean实例的
见图
5.spring手写ioc模块2.0思路分析
* BeanDefinition解析阶段
* 将bean标签解析成BeanDefinition对象
* 将BeanDefinition对象存储到Map集合
* Bean实例创建阶段(只是针对单例bean存储)
* 根据beanName读取存储单例bean实例的Map集合,查找是否有指定beanName的bean实例。
* 有则返回
* 没有则进行bean实例的创建
* 根据beanName读取存储BeanDefinition信息的Map集合,获取对应的BeanDefinition对象
* 取出BeanDefinition对象中存储的class信息,去通过反射创建Bean实例
** ???
* 取出BeanDefinition对象中存储的PropertyValue集合信息,去对刚创建的Bean实例,进行依赖注入
** TypedStringValue
** RuntimeBeanReference
* 取出BeanDefinition对象中存储的initMethod信息,去完成初始化操作
* 将创建出来的对象,放入存储单例bean实例的Map集合中
6.spring手写ioc模块3.0借鉴源码进行改造
* 面向对象
* 设计模式
7.spring中源码的入口
见Spring课件中的源码阅读篇
以上是关于spring的主要内容,如果未能解决你的问题,请参考以下文章