1.1、Spring框架的DI和IOC
IOC:控制反转,指将对象的创建权,转交给Spring容器;
DI:依赖注⼊,指Spring创建对象时,将对象依赖属性 通过 配置进⾏注⼊;
依赖注⼊(DI)和控制反转(IOC)是从不同的角度的描述的同⼀件事情,通过引⼊IOC容器,利⽤ 依赖关系注⼊的⽅式,实现对象之间的解耦。
Spring的bean的scope作⽤域
singleton:单例,默认值,spring的IOC容器中只会存在⼀个该bean;调⽤getBean⽅法返回是同⼀个对象,实例会被缓存起来,效率⽐较⾼;
prototype: 多例,调⽤getBean⽅法创建不同的对象,会频繁的创建和销毁对象,开销⼤;
其他很少使用:request :每个Http请求都会创建⼀个新的bean;session: 每个Http Session请求都会创建⼀个新的bean;
<!--<bean id="video" class="net.xdclass.sp.domain.Video" scope="singleton"> --> <bean id="video" class="net.xdclass.sp.domain.Video" scope="prototype"> <property name="id" value="9"/> <property name="title" value="Spring 5.X课程" /> </bean>
1.2、AOP
Aspect Oriented Program⾯向切⾯编程:一种思想;在不改变原有逻辑上增加额外的功能;在原有逻辑上增加非核心关注点功能;解耦、统一处理横切关注点、方便增加额外非核心功能;
核心关注点:核心业务逻辑、业务功能; 横切关注点:日志信息、权限等,非核心的额外功能;
横切关注点:非核心的额外功能;需要或可以做拦截处理;比如:日志处理、权限认证处理等
通知 Advice:需要在关注点上做的逻辑;比如:需要处理日志,需要调用通用方法等;
连接点 JointPoint:运行过程中需要插入切面的位置,一般在方法的前后;
切⼊点 Pointcut:满足规则的连接点;运行过程中满足规则的切面位置,会运行相应的通知处理逻辑;
切⾯ Aspect:切⼊点+通知;在切入点执行相应的通知处理逻辑;通常是一个类,在类中某地方 某时间执行某个逻辑;
⽬标 target:目标类,业务逻辑类,需要增加额外功能的业务逻辑类;
织⼊ Weaving:将某个切⾯(某个类)应⽤到 ⽬标方法上;
比如:目标类-订单类;连接点-增删改查订单;切入点-增删改查的哪些地方需要增加通知;通知-做日志处理;切面-地点、时间、逻辑;织入-将切面逻辑应用到目标方法;
1.3、AOP的静态代理、动态代理
静态代理:代理类 需要与目标类实现同一样接口,代理类接收目标类对象,在点用目标类方法前后增加相关的额外功能;
优点:在目标类的基础上实现额外功能,不需要修改目标类代码; 缺点:代理类要不断的实现接口的方法,代码冗余;
动态代理:在程序运⾏时,运⽤反射机制 动态创建目标对象;
JDK动态代理:目标类必须实现一个接口,代理类不需要实现接口,代理类通过反射获取接口类对应的实例;JDK自带功能;
CGLib动态代理:目标类不需要实现接口,代理类动态创建一个目标类的子类对象,通过继承来实现;不能应用于final类、private⽅法和static⽅法;需要引⼊第三⽅包;
场景: 如果⽬标对象实现了接⼝,则默认采⽤JDK动态代理,也可使⽤CGlib动态代理;
如果⽬标对象没有实现接⼝,则采⽤CgLib进⾏动态代理;
@Aspect声明是切面;在方法前增加@Before、@After等通知注解;
<aop:config><aop:aspect id="time" ref="timeHandler"><aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))" /><aop:before method="printTime" pointcut-ref="addAllMethod" /><aop:after method="printTime" pointcut-ref="addAllMethod" /></aop:aspect></aop:config>
流程描述
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器。
3、处理器映射器找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet调用HandlerAdapter处理器适配器
5、HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
6、Controller执行完成返回ModelAndView
7、HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9、ViewReslover解析后返回具体View
10、DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
11、DispatcherServlet响应用户
Spring
1、bean加载顺序,B方法上加注解上注解@DependsOn({"a"}),意味B依赖A,先加载A;@Order类标记,越小越早加载;Spring有很多扩展点,BeanFactoryPostProcessor加载所有bean之前做一些逻辑;业务层flag,check-act;
2、大对象-大字符串/一维数组;超eden直接old,超old直接抛异常;超-XX:PretenureSizeThreshold字节直接放old,默认0不生效;
3、替换jar:写java编译替换jar中,同路径同名覆盖加载; 先加载目录下config+目录,再加载classpath下的config+目录;
4、mvc-前端控制器、映射器、处理器、视图解析器;视图、modelAndView、填充模型数据; @ResponseBody数据绑定-字符串到JAVA对象的数据转化;
5、装配:根据依赖关系将bean组装在一起;通过名字、类型、构造器、自动组装等方式;
6、核心:BeanDefinition、BeanDefinitionReader、BeanFactory、ResourceLoader、ApplicationContext;
7、bean生命周期:扫描过滤加载bean,初始化bean,setBeanName/BeanFactory/Context,BeforeInitialization/afterPropertiesS/afterInitialization,使用,destory;
8、单例bean安全问题:理论上全局变量和静态变量都会引起线程安全问题,用threadlocal、多例模式、加锁方式实现线程安全;
9、Spring用到的设计模式: 单例模式-bean,代理模式-AOP,工厂模式-创建bean;
Spring 框架中的核心组件只有三个:Core、Context 和 Beans,其中Beans 组件最为重要;
面试常问:
1、最常用的BeanFactory 实现是XmlBeanFactory 类,它根据XML文件中的定义加载beans。该容器从XML 文件读取配置元数据并用它去创建一个完全配置的系统或应用。
2、bean 装配是指在Spring 容器中把bean组装到一起,前提是容器需要知道bean的依赖关系,如何通过依赖注入来把它们装配到一起。
3、Spring 容器能够自动装配相互合作的bean,这意味着容器不需要<constructor-arg>和<property>配置,能通过Bean工厂自动处理bean之间的协作。
4、有五种自动装配的方式,可以用来指导Spring容器用自动装配方式来进行依赖注入。
- no:默认的方式是不进行自动装配,通过显式设置ref 属性来进行装配。
- byName:通过参数名 自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byname,之后容器试图匹配、装配和该bean的属性具有相同名字的bean。
- byType::通过参数类型自动装配,Spring容器在配置文件中发现bean的autowire属性被设置成byType,之后容器试图匹配、装配和该bean的属性具有相同类型的bean。如果有多个bean符合条件,则抛出错误。
- constructor:这个方式类似于byType, 但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。
- autodetect:首先尝试使用constructor来自动装配,如果无法工作,则使用byType方式。
5、自动装配的局限性是:
- 重写: 你仍需用 <constructor-arg>和 <property> 配置来定义依赖,意味着总要重写自动装配。
- 基本数据类型:你不能自动装配简单的属性,如基本数据类型,String字符串,和类。
- 模糊特性:自动装配不如显式装配精确,如果有可能,建议使用显式装配。
spring:spring各种配置+组件各种配件
引入dubbo包,properties配置dubbo/zk的应用名、服务注册ip地址;config.xml中配置是生产者 zk的ip,去声明提供服务类;service.xml中去配置是消费者 zk的ip,声明要使用的服务类,是否检查;zkserver 去启动重启服务;zkcli去登录查看服务;ls dubbo * providers/consumers,invoke去手动触发一次service类的方法;
@service、@resource、@value、@requestMapper、@responseBody,cookies中token联查redis获取登录信息;
7种事务传播行为-回滚:没有则建新,没有则不用,没有则报错;总是新的挂旧的,总是不用挂有的,总是不用抛异常;嵌套事务+带多保存点事务;
MQ安装后,启动nameserver和broker,扩展包有可视化页面;properties去配置MQ的服务ip地址,生产者/消费者的groupId和topic;xml中配置其消费有序,代码中设置queueId来生产有序;
redis-server启动;redis-cli 的keys/del等去查看数据,treeNMS可视化管理;redisTemplate.opsForValue().set/hasKey;
canal:mysql设置binlog为row模式;数据库权限;配置数据库ip端口等;配置MQ的nameserver/topic/priducergroup等;表结构,变更前后数据等信息;
seata:分布式事务,引包+配置服务+创建seata库表;2pc应用层而不是数据库层,seata两阶段(依赖TC事务协调器决议,提交+全局回滚,undo_log)(2PC--投票准备+事务提交/回滚;TCC--Try+Confirm+Cancel );
mycat:分布式数据库,数据库代理,与多个数据库通信;拦截SQL+分片/路由/读写等分析+发往真实数据库+处理返回结果;分片字段/方法等定位;分页查:普通分-根据返回顺序,每次结果不一致;排序分-查询每个DB,有序改limit 0,m+n; join的表必须同分布,不友好; 弱一致性,准备+提交/回滚;会等待超时;
创建配置mycat的数据库;配置各个数据库的ip和连接配置等,配置表字段分片规则等;
zk注册中心,目录节点 类似树;leader选举,同步数据;后期是leader写同步到follow节点;
dubbo生产消费,通过xml中,配置
retries 再重试次数/cluster 失败后操作-failfast报错、failsafe忽略等实现容错;
配置loadbalance实现负载均衡
等,默认romdom随机,基本没人修改,还有 权重轮训/hash/最小活跃等;
实体-属性-联系;流程;业务方向,所属业务范畴,所属于的领域;DB-service-view;
spring boot:简化Spring配置+组件各种配置
默认带各种starter,Spring-web/webmvc--starterweb,junit/Springtest-startertest;集成了tomcat,支持热部署-pom引入devtools记录修改的类去重新加载重启速度非常快;使用nacos管理配置文件,能动态刷新;pom中rocketMq还是要配置+版本号;使用starter-parent提供maven默认依赖,省版本号;单元测试@SpringBootTest/@test注解;
nacos:配置信息管理组件,下载安装可视化,可以配置数据库管理登录用户;springboot中bootstrap.properties配置nacos的服务IP地址;要保持项目中artifactId/application.name和nacos中的yaml名称一致;缩进分层的样式;
swagger:在线API接口文档,pom引入swagger包,拦截器配置页面静态资源跳过权限,controller配置@api tag/@apiOperation value httpmethod/@ApiImplicitParam等注解来增加类与方法的描述信息;
入口是@SpringBootApplication标记的main方法;执行自动配置EnableAutoConfiguration/自动扫描ComponentScan等注解; 会从classpath中寻找spring.factories文件汇总形成IOC容器配置类,并扫描符合规则的组件和bean加载到IOC容器中;通过执行静态run方法加载Application对象,执行对象run方法来加载各种监听,执行监听初始化环境,创建并刷新上下文;
Spring cloud:整套微服务
Eureka 服务治理,生产消费和注册中心;starter-eureka-server/starter-eureka等以及启动类main方法的@EnableEurekaServer注解和yaml上配置的端口ip和service-url等进行配置服务;通过DiscoveryClient工具类获取服务的实例;节点平等;自我保护-85%节点没心跳则不剔除不同步;
Eureka:Client向Server注册服务ip端口url,消费者向注册中心获取提供者地址缓存到本地,从缓存读取调用;注册中心向订阅者提供宕机信息;节点每30s向注册中心发送心跳续约服务;90S无心跳剔除注册列表; 自我保护:统计15分钟内的失败比例,大于85%则不剔除防误杀,等待恢复心跳;
工作流程:等待注册或集群复制;注册/心跳续约/自我保护;获取服务到本地缓存;缓存无服务去注册中心刷新再缓存;缓存获取地址调用;
通过Hystrix熔断降级实现容错;保证可用可靠性,防止崩溃;启动类mian方法加@EnableCircuitBreaker断路器注解
熔断:某服务不可用或超时,则暂停调用;降级:某服务相应慢,则舍弃非核心接口及数据,做好报错信息;
服务雪崩:硬件/网络/bug;缓存击穿大量请求;
原理:命令模式通过HystrixCommand类包裹调用服务的run方法封装成单独线程和一个线程池,监控的成功失败和超时,根据阈值实时修改其降级和熔断配置;
通过Ribbon实现负载均衡;默认是轮训;配置yaml中ribbon loadbalanceRule规则/read请求超时/connect连接超时/重试次数等;@LoadBalanced注解;
Feign,基于Ribbon,集成了Hystrix;
6、Spring-cloud
Rest与RPC:RPC提供与调用方式依赖强,需要定义每个接口,严格按照版本控制;Rest是一种松耦合,约定规范,借助swagger来实现在线API接口文档;
ZK:CP强一致性,选举不可用,是一个进程;Eureka:CP可用性,自我保护机制;
feign:集成来Ribbon,接口注解;
bus:通过消息代理连接各个节点;-pom+rabbitMq
断路器:自身或网络故障,很多请求等待响应;全开是请求不到服务;半开是有迹象恢复则调用成功则关闭;关闭是服务正常调用;
Zuul路由网关:分发消费者的请求;
Gateway:取代来Zuul,除了分发请求,还有流量控制,过滤请求等;
config:服务配置文件管理;