AOP的底层实现,动态代理是如何动态的?
AOP是对OOP的补充,抽离可复用模块,采用动态代理实现,有接口采用JDK动态代理,无接口采用CGLib实现;JDK动态代理基于Java反射机制实现,通过实现接口,反射生成代理类ProxyXX,只能代理接口是因为代理类本身已经extends了Proxy类,而java是不允许多重继承的,但是允许实现多个接口,主要接口:InvocationHandler、Proxy; cglib动态代理:基于ASM机制实现,高性能高质量,继承生成子类实现,通过字节码技术为被代理类创建子类,子类拥有父类的引用,并在子类中采用方法拦截的技术拦截所有父类方法的调用,比JDK耗时,主要接口:MethodInterceptor、Enhancer,无需实现接口,达到代理类无侵入 ;应用场景包括记录日志、监控方法运行时间、权限控制、事务管理(调用方法前开启事务, 调用方法后提交关闭事务);
讲讲Spring加载流程
web.xml中配置了ContextLoaderListener监听器,启动时通过监听器加载Spring, Spring根据配置路径加载Spring文件创建Bean的实例,并将加载好的bean放入ServletContext容器中;容器初始化完成后就初始化DispatcherServlet,DispatcherServlet初始化上下文包括处理器映射器,处理器适配器,视图解析器等,最后再将初始化完成的Servlet注册到ServletContext中,这样每个Servlet都可以持有自己的上下文,同时又能共享根上下文,即IOC容器上下文WebApplicationContext;
讲讲Spring事务的传播属性
事务传播属性就是存在多个事务是如何处理,根据是否存在事务、当前事务是新建、不建、抛异常、嵌套、加入已有事务(默认)等分成多种;默认是REQUIRED,存在事务时加入当前事务,没有则新建事务;
Spring如何管理事务的
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的;事务实现方式包括编程式事务(TransactionTemplate写代码手动提交)、声明式事务(Transactional注解自动提交);主要类包括PlatformTransactionManager(事务管理器接口,Spring 有默认实现,或者需要其他持久层框架实现)、TransactionDefinition(事务基本属性:隔离级别、传播行为、是否只读、事务超时、回滚规则)、TransactionStatus(记录事务状态);事务属性包括事务传播行为(存在多个事务是如何处理):根据是否存在事务、当前事务是新建、不建、抛异常、嵌套、加入已有事务(默认)等分成多种;事务隔离级别:默认使用数据库的事务隔离级别、READ_UNCOMMITTED、READ_COMMITTED、REPEATABLE_READ、SERIALIZABLE;事务超时:支持定义事务执行超时时间;事务回滚规则:定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚;事务是否只读:表示这个事务只读取数据但不更新数据, 这样可以帮助数据库引擎优化事务;
Spring怎么配置事务(具体说出一些关键的xml元素)
配置事务的方法有两种:基于XML的事务配置和基于注解方式的事务配置;Spring的事务管理是通过Aop的方式来实现;注解是@Transactional,XMl配置bean DataSourceTransactionManager,属性有propagation、isolation、rollback-for、timeout、no-rollback-for、read-only;
Spring bean的作用域和生命周期
Bean的加载(生命周期):通过解析XML和扫描注解获取Bean定义、实例化bean、设置对象属性(DI)、处理xxAware接口、执行BeanPostProcessor的before方法、执行初始化方法init-method、执行BeanPostProcessor的after方法即完成bean的创建;销毁:调用DisposableBean的destory方法、调用destroy-method方法;
Bean作用域:singleton、prototype、request、session(同一个session共享实例)、global-session(所有session共享实例)、application(ServletContext共享一个实例);
Spring的bean配置的几种方式
1. 基于XML配置:配置beanId、class、setter/getter、constructor;2. 基于Java注解配置:component-scan、@Component、@Repository、@Controller等; 3. 基于Java类的JavaConfig:@Configuration、@Bean、@Import等;
属性注入和构造器注入哪种会有循环依赖的问题?
依赖注入有三种方式:属性注入Setter、构造函数注入、工厂注入(配置factory-method);构造函数注入的前提是入参引用必须就绪,如果2个对象构造函数中互相引用就会造成循环依赖的死锁问题,解决方法是其中一个对象采用Setter注入方式;
Spring的controller是单例还是多例,怎么保证并发的安全。
controller默认是单例的,线程不安全,线程安全的方法:1. 不要在controller中定义成员变量; 2. @Scope(“prototype”)将其设置为多例模式;3.在Controller中使用ThreadLocal变量;
Spring的监听器
javax.servlet的监听器:监听ServletContext、Session、Request对象的创建、销毁、属性变化包括ServletContextListener、HttpSessionListener、ServletRequestListener、ServletContextAttributeListener、HttpSessionAttributeListener、ServletRequestAttributeListener;
Spring的监听器:WebAppRootListener(容器启动时设置Web Root ;Path属性)、ContextLoaderListener(容器启动时装配ApplicationContext配置信息)、Log4jConfigListener(初始化Log4j配置),都实现了ServletContextListener接口;另外ApplicationListener可对指定事件进行监听,Spring实现了多种事件如ApplicationReady/Started/FailedEvent等,也可以自定义事件和事件发布ApplicationContext.publishEvent;
是否用过Autowire注解
@Resource是JDK开发的,按照名称装配,如果名称找不到就按照type;@Autowire是Spring开发的,按照type来装配,可结合@Qualifier按照名称装配,可设置byType、byName、autodetect;
Spring IOC是什么?优点是什么?
IOC即创建对象的主动权和时机的权利由类本身转移给Spring容器,采用反射实现组件间松耦合,和DI一个意思只是描述角度不同;3种注入方式:构造器、Setter、实例工厂、静态工厂、注解;优点是内存控制:统一管理对象,避免对象乱创建导致额外的内存开销,便于内存的优化;降低耦合度:便于项目的扩展、易于维护;
Java动态代理和cglib动态代理的区别
CGLIB:高性能高质量,继承生成子类实现,通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,比JDK耗时,主要接口:MethodInterceptor、Enhancer;JDK动态代理通过实现接口,反射生成代理类ProxyXX,只能代理接口是因为代理类本身已经extends了Proxy类,而java是不允许多重继承的,但是允许实现多个接口,主要接口:InvocationHandler、Proxy;
SpringMVC中DispatcherServlet运行原理,用到的注解?
用户请求发送至前端控制器DispatcherServlet、DispatcherServlet调用HandlerMapping获取Handle、HandlerMapping根据URL找到handle及所有拦截器生成调用链返回给DispatcherServlet、DispatcherServlet 调用 HandlerAdapter处理器适配器执行、HandlerAdapter 调用handle执行并返回ModelAndView给DispatcherServlet、DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析、ViewResolver解析后返回具体View、DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)、DispatcherServlet响应用户;
常用注解:@RequestMapping、@RequestParam、@PathVariable、@ResponseBody、@RequestBody
Spring Boot比Spring做了哪些改进?Spring 5比Spring4做了哪些改进
SpringBoot的改进:简化难度,提供启动器,快速上手,独立运行,简化配置,自动配置,无代码生成和XML配置,无需部署war文件;Spring5的改进:使用JDK8的特性、响应式编程支持、函数式web框架、Kotlin支持;
SpringBoot启动机制
每个SpringBoot程序都有一个主入口main方法,main里面调用SpringApplication.run()启动整个spring-boot程序,该方法所在类需要使用@SpringBootApplication注解,启动流程分为3部分,第1步:通过SpringApplication.run方法进行SpringApplication类的初始化模块,配置一些基本的环境变量、资源、构造器、监听器;第2步:启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块;第3步:自动化配置模块,该模块作为springboot自动配置核心,通过SpringBootApplication注解引入SpringBootConfiguration(引入@Configuration相当于JavaConfig)、ComponentScan、EnableAutoConfiguration(引入@Import(AutoConfigurationImportSelector.class))3个注解,AutoConfigurationImportSelector的selectImports()方法通过SpringFactoriesLoader.loadFactoryNames()扫描所有jar包的META-INF/spring.factories文件获取KeyValue即自动配置类JavaConfig、解析这些Spring容器配置类即可完成自动加载;
Spring Cloud熔断机制介绍
通过Spring Cloud Netflix Hystrix组件解决服务雪崩、控制和保护第三方依赖、阻止故障的连锁反应、快速失败并迅速恢复、回退并优雅降级;
使用:继承HystrixCommand或HystrixObservableCommand,通过execute、queue、observe、toObservable方法执行;@HystrixCommand配置策略;
资源隔离:线程池隔离:将每个command放到单独的线程池中,线程池满则拒绝服务;缺点:增加了排队、调度、上下文切换的开销;信号量隔离:不启动新线程,在原有线程中执行,没有上下文切换的开销,通过信号量限制并发资源数量,拿不到信号量则拒绝进入fallback,不支持异步执行和超时;
熔断器:初始关闭状态,若统计时间窗内请求数超过阈值并且错误率超过50%则打开(请求数不够则不处理);5秒后为半开状态,允许一个请求执行;若成功则熔断器关闭,失败则打开;
回退降级:command执行抛异常、熔断器打开、线程池信号量满、命令执行超时都会进入降级;快速失败:直接抛异常;无声失败:返回空、静态或缓存数据;
Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?
SpringCloud基于Http,更加灵活;Dubbo基于RPC调用的方式,数据传输需要序列化和反序列化,性能更快;SpringCloud更新快,在社区活跃度上SpringCloud优于Dubbo;在生态上,SpringCloud也是优于Dubbo的,Dubbo没有配置中心、服务网关,熔断器不够完善;
网友评论