Spring全家桶框架篇

发布时间:2026/7/2 4:18:38

Spring全家桶框架篇 一. spring篇1、spring框架中单例的bean是否安全不安全。2、spring支持哪几种作用域1. singleton作用域prototype作用域request作用域session作用域3、spring的事务隔离级别有哪几种五种隔离级别。default默认的隔离级别已连接数据库的隔离级别为准4、spring的事务什么时候会失效项目中spring事务的实现通过transaction注解实现。几种失效的场景1. 注解修饰的方法非public的spring的AOP只对public修饰的方法进行代理。2. 同一个类中调用了注解修饰的方法Spring 的事务是通过AOP 代理实现的Transactional是作用在代理对象上的而this调用的是当前对象本身绕过了代理对象。Servicepublic class UserService {public void outerMethod() {// 调用内部带事务的方法this.innerMethod(); // 无法触发事务}Transactionalpublic void innerMethod() {// 不生效}}解决方法获取该类的代理对象然后再进行调用。Servicepublic class UserService {public void outerMethod() {// 获取代理对象再调用方法才能触发事务((UserService) AopContext.currentProxy()).innerMethod();}Transactionalpublic void innerMethod() {// 事务生效}}3. 注解修饰的方法不能用try catch来进行捕获通过try catch捕获了异常spring不能感知因此不能进行回滚。解决方法抛出异常或者手动设置事务回滚。4. 使用的数据库引擎不支持事务5. Spring 容器未管理该类Transactional只有在类被 Spring 容器管理被扫描并注册为 Bean时才有效。6. final修饰的类或者方法7. 抛出的异常类型不匹配Spring 默认只对未被捕获的运行时异常RuntimeException及其子类或Error回滚。对Checked Exception受检异常如IOException默认不会回滚。解决方法可以通过配置rollbackFor属性显式指定。Transactional(rollbackFor Exception.class) public void doSomething() throws Exception{throw new Exception(This will now trigger rollback.);}总结场景是否失效原因同类中调用事务方法✅ 失效没有通过代理对象非public方法✅ 失效Spring AOP 只代理public方法或类是final✅ 失效无法被代理捕获异常不抛出✅ 失效Spring 不感知异常抛出CheckedException✅ 失效默认不回滚多数据源或事务管理器配置错误✅ 失效事务不走指定TransactionManager非 Spring 管理的 Bean✅ 失效不经过 Spring AOP5. Beanfactory和factoryBean1. beanfactorybean的工厂负责创建和管理bean。2. factorybean是一种特殊的bean的对象可以创建其它的bean通过getobject方法返回。applicationContext和BeanFactory的区别?Beanfactory是spring容器的根接口里面提供了一些方法的约束和规范为了满足更多的需求。applicationContext实现了这些接口并在这些接口的基础上面进行扩展提供了更丰富的api。6. Bean的生命周期总的来说有五个阶段。实例化属性赋值初始化使用销毁。分说1. bean的实例化通过反射的方式来实现在源码中有个createbeaninstance方法专门用来生成bean的实例。2. 当bean的对象创建完成以后对象的属性都是默认的需要对bean的属性进行赋值。在源码中是通过populatebean方法完成对象属性赋值的。3. 将bean对象中设置容器属性会调用invokeawaremethod方法将容器的属性设置到bean对象。4. 调用beanpostprocessor中的前置方法来进行bean的一些扩展性工作5. 调用Invokeinitmethod方法来完成初始化工作7. 什么叫做AOP任何一个系统都是由不同的组件组成的每个组件负责不同的功能有的组件与业务无关例如日志权限事务等。这些非核心的业务经常需要融入核心的业务代码中去这样以来会显得代码冗余。我们将这些代码抽取成一个切面注入到目标对象中去。AOP正是利用这种思想通过动态代理的方式对需要注入切面的对象进行代理在进行调用的时候将公共的逻辑直接添加进行而不需要修改原有的代码的逻辑。使用举例一个项目里面100个方法前后添加日志采用AOP的思想。1.切面 2. 连接点 3. 通知 4. 切点 5. 引入 6. 目标对象8. 什么叫做IOC之前我们创建对象都是通过new的方式手动创建的有了IOC之后我们需要创建对象只需要告诉IOC容器IOC自动帮我们创建然后返回给我们。控制反转是一种思想将对象的创建交给IOC容器去创建而不是我们主动的去创建。依赖注入DI是控制反转的具体实现将一个类所依赖的对象在容器运行的时候动态的注入进来而不是主动的去获取。依赖注入的三种方式1. 通过构造函数方式注入 2. 通过set方式注入 3. 通过字段注入注入方式描述示例构造方法注入通过构造函数传入依赖Autowired public UserService(UserRepo repo)Setter 方法注入通过 set 方法注入依赖Autowired public void setRepo(UserRepo repo)字段注入通过反射直接注入字段Autowired private UserRepo repo;spring中常见的设计模式及应用场景1. 工厂模式beanfactory和applicationcontext主要用来创建bean对象。2. 单例模式spring 默认的bean作用域是单例的。3. 代理模式AOP的底层原理是通过JDK动态代理或CGLIB代理实现的。4. 适配器模式HandlerAdapter适配不同的contoller5. 策略模式springmvc中处理请求方式的选择如handlermapping6. 模版方法模式jdbctemplate,resttemplate。封装统一流程子类实现部分差异。7. 观察者模式spring的事件发布机制。applicationevent,applicationlistenerspring,springmvc,springboot区别与联系spring是一个一站式的轻量级开发框架。spring mvc: 是spring基础上的一个mvc框架是spring框架中web层的一部分。springboot与spring mvc相比spring boot专注于微服务的开发约定大于配置同时内置tomcat服务器。9. spring的三级缓存一级存放完整的bean实例这些bean实例可以拿来直接使用的。二级存放半成品bean实例即已经实例化完成但是没有完成属性的注入。三级存放生成代理对象的工厂ObjectFactory主要用来创建代理对象实例放入二级缓存。10. spring的三级缓存如何解决循环依赖问题的总结spring的一二级缓存主要用来解决普通的循环依赖问题带有AOP的循环依赖需要通过三级缓存来进行解决。分1. 不带有AOP形式的循环依赖问题spring创建A对象的时候会将实例化完成的半成品对象放入二级缓存。创建B对象实例化完成以后发现依赖于A对象会从二级缓存中拿到A对象完成属性的注入生成成品的B对象放入一级缓存。然后A对象从一级缓存中拿到成品对象完成属性的注入。2. 带有AOP形式的循环依赖问题1. spring创建A对象的时候不能把原始对象直接暴露出去需要对它进行AOP动态代理2. 此时的动态代理对象并没有创建完成不能直接放入一二级缓存。3. spring把创建代理对象的objectfactory工厂对象放入三级缓存4. 创建B对象的时候发现需要依赖A对象从一二级缓存中查找没有从三级缓存中通过objectfactory工厂创建A的代理对象放入二级缓存。5. 后续继续创建流程完成注入二. springboot篇nacos服务注册与发现工作的流程服务注册: 服务启动的时候会将自己的服务信息注册到nacos上面服务名,ip和端口号服务续约: 服务启动以后每隔5s中会向nacos发送心跳信息用来保活如果nacos长时间15s钟没有收到服务端发来的心跳信息会认为服务实例不健康甚至剔除。服务发现消费者在进行调用的时候会根据服务名从nacos的服务端获取服务列表信息并在本地nacos的客户端缓存做负载均衡和调用。服务下线和宕机1. 如果服务关闭nacos的客户端会自动发起注销请求2. 如果服务异常宕机nacos服务端会根据心跳机制剔除服务eraka和nacos的区别与联系nacos优点1. 支持配置中心和热部署refreshScope注解和ValueRestControllerRefreshScopepublic class ConfigController {Value(${my.config.value})private String configValue;GetMapping(/config)public String getConfigValue() {return configValue;}}2. 支持健康检查心跳机制3. 动态服务推送当nacos的服务端维护的实例有发生变更以后会主动的向订阅了该服务的客户端推送数据的状态。客户端和服务端之间是建立的长连接。服务端主动推送客户端被动接收。springboot的自动装配原理从spingbootapplication注解开始讲起1. springbootconfigration注解的内部有个configration注解表明当前的类是一个配置类。点击configration注解里面有个component注解表明当前的类也是spring容器的一个组件。2. componentscanspringboot启动的时候会扫描当前包以及其子包下面所有的标注了controller,service,component,configration的注解注册成bean对象定义到spring的容器里面。3. enableautoconfigration总的来说根据当前类路径下面的依赖筛选出符合条件的bean到spring的容器里面省去手动 配置的麻烦。具体说明点击注解内部有个Import注解该注解里面有个AutoConfigurationImportSelector类主要用来选择候选的配置类信息注册bean对象到spring的容器。获取信息的来源主要是spring-boot-autoconfigure包下面的mate-inf/spring包下面的spring.factory或者imports配置文件里面的配置信息通过SpringFactoriesLoader工具类来进行扫描这些配置信息的全路径类型通过反射的机制对应到代码的实体类然后通过代码中getCandidateConfigurations方法来获取这些候选的配置类信息通过conditionalxxx注解筛选出符合条件的配置类信息注册为bean定义到spring的容器。1.自动配置自动装配使用了策略模式 条件注解Conditional工厂模式实现类在spring.factories中注册SPI机制根据不同条件如类是否存在、Bean 是否存在来动态注入配置例如ConditionalOnClass(DataSource.class)Beanpublic DataSource dataSource(){return new HikariDataSource();}这是一种典型的策略模式 工厂模式组合。2. 如何自己创建一个starter?3. springboot中常用的注解?RequestMapping映射请求路径把它映射到对应的方法上。RequestMapping(value /user, method RequestMethod.GET)public String getUser() {return user;}RequestBody用于接收请求体的json对象把它映射为java对象。ResponseBody将数据封装成json返回给前端。RequestParam用于获取请求参数。可以通过true或false设置为必传GetMapping(tree)public Object getOrgTreeData(RequestParam(required false) String deptId, RequestParam String type)CrossOrigin注解标注在类或者方法上面解决跨域的问题。什么是跨域问题跨域是浏览器的同源策略导致的到前端代码尝试访问不同源的协议的端口或者域名不一致资源的时候浏览器会对其进行阻止。在后端代码添加cros头。比如springboot提供的crossorigin注解全局cross配置或者Nginx的反向代理。为啥只有浏览器端会有跨域问题为了对浏览器端进行保护防止黑客攻击。1.使用crossorign注解CrossOrigin(origins http://localhost:8080)GetMapping(/user)public User getUser() {return new User(Tom, 18);}2. 使用cross全局配置类Configurationpublic class CorsConfig implements WebMvcConfigurer {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**).allowedOrigins(*).allowedMethods(GET, POST, PUT, DELETE).allowCredentials(true).maxAge(3600);}}3. 使用Nginxlazy(懒加载当springboot启动的时候不会创建被lazy标注的类的bean对象而是第一次使用的时候才会创建。4. springboot如何实现让bean依赖其它的一些bean创建完成以后再进行加载1. 通过depand on注解ComponentDependsOn({beanA, beanB})public class MyBean {public MyBean() {System.out.println(MyBean 被创建beanA 和 beanB 已经初始化);}}2. PostConstruct: 常用与spring bean的依赖注入完成以后初始化完成之前调用该注解标注的方法。常用于初始化操作。1.初始化连接池 2.加载缓存数据4.springboot的事件监听机制概念Spring Boot 的事件监听机制是基于Spring Framework 的事件发布-监听模型ApplicationEventPublisher 机制实现的它是典型的观察者模式的应用。核心组件组件说明ApplicationEventSpring 事件的基类自定义事件通常继承它也可以是任意 POJOApplicationListener事件监听器用于接收和处理特定类型的事件ApplicationEventPublisher事件发布器用于发布事件Spring 容器本身就是一个发布器EventListenerSpring 4.2 之后推荐使用的注解式监听器简洁易用事假监听机制流程事件发布器初始化Spring 容器初始化时ApplicationContext继承了ApplicationEventPublisher接口本身就是事件发布器。监听器注册容器启动时会扫描并注册实现了ApplicationListener接口的 Bean或者带有EventListener注解的方法。发布事件使用applicationContext.publishEvent(event)方法发布事件容器会自动找到匹配的监听器并异步或同步调用它们。事件分发器由SimpleApplicationEventMulticaster事件广播器分发事件给对应的监听器。默认同步执行监听器方法也可以自定义为异步执行通过设置线程池等。示例代码1. 定义一个事件类public class MyEvent extends ApplicationEvent {private String message;public MyEvent(Object source, String message) {super(source);this.message message;}public String getMessage() {return message;}}2. 创建事件监听器Componentpublic class MyEventListener {EventListenerpublic void handleEvent(MyEvent event) {System.out.println(监听到事件 event.getMessage());}}3. 发布事件例如在 Controller 或 Service 中Autowiredprivate ApplicationEventPublisher publisher;public void doSomething() {System.out.println(主业务逻辑执行);publisher.publishEvent(new MyEvent(this, 这是一个自定义事件));}spring中常见的内置事件事件类型说明ApplicationStartedEventSpring Boot 启动开始时ApplicationReadyEvent应用准备就绪ContextRefreshedEventApplicationContext 初始化/刷新完成ContextClosedEventApplicationContext 关闭三.springmvc篇四.springGloud篇springboot和springcloud之间的区别springboot: springboot是专注于进行单个服务的开发。springcloudspringcloud专注于构建和管理分布式系统中的多个服务解决服务之间的协作问题。RPC和springCloud的区别RPC是一种远程调用的通信机制它解决的是不同服务之间如何进行高效通信的问题。springcloud用来快速搭建和管理一个微服务专注于整个生态的治理。eraka进行服务注册与发现OpenFeign进行远程调用Ribbon负载均衡gateway网管histric服务的熔断限流降级。五. mybatis篇概念mybatis是一款优秀的持久层框架它通过xml或者注解让sql语句与java的实体类进行关联。它使开发者只需要关注编写sql语句本身不需要关注加载驱动创建连接创建statement等。提供了比jdbc更灵活、方便操作数据库的方式。优点1. sql由开发者手动编写灵活度高2. 支持动态sql如ifforeach标签等3. 支持结果集到java对象的动态映射4. 缓存机制一级缓存默认开启sqlsession级别的二级缓存mapper级别的缺点1. 当sql语句比较复杂的时候sql语句编写工作量大。尤其当字段信息比较多连表比较多 的情况下需要sql编写人员有一定的功底。2. sql语句比较依赖于数据库不能随意更换数据库因此sql语句的移植性比较差。Mybatis的执行流程1. 加载配置文件信息mybatis-config.xml2. 获取SqlSessionFactory对象3. 创建sqlsession对象4. 获取Mapper代理接口5. 执行sql6. 提交/回滚7. 关闭session实体类属性名和表中字段名不一样 怎么办?通过 resultMap 中的result来映射字段名和实体类属性名的一一对应的关系。select idgetOrder parameterTypeint resultMaporderResultMap select * from orders where order_id#{id} /select resultMap typecom.jourwon.pojo.Order idorderResultMap !–用id属性来映射主键字段– id propertyid columnorder_id !–用result属性来映射非主键字段property为实体类属性名column为数据库表中的属性– result property orderno column order_no/ result propertyprice columnorder_price / /resultMap#{}和${}的区别#{}当使用#{}时候mybatis会进行预编译将#{}占位符替换成 ?然后使用参数值进行替换。${}: 当使用${}时候不会进行预编译。直接进行纯字符串的替换。模糊查询怎么写concat(%,#{question},%)使用concat函数进行拼接4. mybatis的一级和二级缓存一级缓存sqlsession级别的缓存本地的缓存默认开启只在当前的会话有效。缓存机制当你在一个sqlsession多次执行相同的sql的时候第一次从数据库查第二次从缓存中查。二级缓存mapper级别的缓存可跨多个会话使用需手动开启。二级缓存的原理基于mapper映射级别的核心原理通过维护一个缓存容器cache的实现类来实现多个sqlsession共享数据的。原理流程如下查询时SqlSession 会先查一级缓存本地缓存。如果一级缓存没有命中再查二级缓存。如果二级缓存也没有命中就去查询数据库然后将结果写入一级缓存SqlSession 关闭后会把一级缓存中可缓存的查询结果写入二级缓存更新时当执行insert/update/delete时会清空对应 Mapper 的二级缓存防止脏数据。二级缓存是线程安全的吗答案是的默认是线程安全的。二级缓存采用装饰着模式对缓存进行来包装:SynchronizedCache装饰器会对缓存访问加锁使用synchronized。保证并发下的数据一致性.已经有了一级缓存为啥还需要使用二级缓存1. mybatis的一级缓存是基于sqlsession级别的 只在当前会话中有效无法在多个请求之间复用。二级缓存是基于mapper映射级别的可以在多个sqlsession之间共享适合读多写少的场景 。它能有效提升系统的性能降低数据库的压力。MyBatis 是如何进行分页的分页插件的原理是什么1. 通过limit关键字2. pagehelperMybatis主要是通过pagehelper来进行分页的主要是拦截Executor的query方法通过动态的修改sql语句通过动态追加sql参数limit/offset字段同时可以统计总记录行数实现无侵入式分页功能。说说 Mybatis 的插件运行原理如何编写一个插件mybatis拦截器通过拦截核心对象的方式实现功能的增强运行原理通过动态代理的方式对目标对象实现功能的增强。实现方法通过实现Interceptor接口并通过Intercepts/Signature指定拦截点。6. mybstis-plus优势1. 无侵入设计通过简单的依赖注入即可增强原有的Mybatis的功能不需要修改原有的配置。2. 内置mapper, service接口可以实现简单的crud操作而无需自己编写sql。3. 内置条件构造器QueryWrapperLambdaQueryWrapper实现复杂的条件查询操作。4. 内置分页插件可以实现分页的功能5. 代码生成器可以根据表结构生成对应的controller,service,mapper,entity7. mybstis-plus与mybatis的比较mybatis是一个灵活的可控的ORM框架适合需要精细控制SQL或者处理复杂的sql场景比如金融系统或者大数据平台。mybatis-plus是mybatis的增强版提供了大量的开箱即用的功能通用的CRUD操作条件构造器代码生成器适合以单表为主的快速开发项目。比如管理后端或者微服务的基础模块的开发。两者在项目中也可以同时使用。六. 拦截器和过滤器的区别过滤器 是servlet的规范在javax.servlet包中。执行的时机是在进入servlet或者向客户端返回的时候。通过实现filter接口实现并在web.xml或者webFilter注解实现。通过dofilter方法实现对应的逻辑。使用场景统一编码跨域请求请求日志。Order(1) Component WebFilter(filterName WebsocketFilter, urlPatterns /chat/webSocket/**) public class WebSocketFilter implements Filter { Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException, ServletException { HttpServletResponse response (HttpServletResponse) servletResponse; String token ((HttpServletRequest) servletRequest).getHeader(Sec-WebSocket-Protocol); response.setHeader(Sec-WebSocket-Protocol,token); filterChain.doFilter(servletRequest, servletResponse); } Override public void destroy() { } }拦截器是spring的规范属于springmvc层的机制主要对controller层进行拦截和增强不会拦截静态资源Controller方法执行的前后执行。使用场景权限认证登录认证业务日志。public class MyInterceptor implements HandlerInterceptor {public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 控制器执行前return true;}public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {// 控制器执行后视图渲染前}public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 请求完成后视图渲染后}}使用场景对比过滤器Filter更偏向与底层。拦截器Intercepter: 偏向于业务层。七. spring的Customizing the Nature of a Bean定制 / 自定义 / 按需求修改控制Bean在创建前、创建后、销毁时做什么事情:实例化Bean↓属性注入↓BeanNameAware↓BeanFactoryAware↓BeanPostProcessor before↓PostConstruct↓InitializingBean.afterPropertiesSet↓自定义 initMethod↓BeanPostProcessor after↓Bean 可使用↓PreDestroy↓DisposableBean.destroy↓destroyMethodContainer Extension PointsSpring负责创建Bean管理Bean注入依赖管理生命周期但有时候我们需要修改 Bean修改 Bean 定义在 Bean 创建前后做事情所以Spring提供了扩展点机制。两个比较重要的扩展点Spring 最核心的 Container Extension Points 有两个1.BeanPostProcessor: 在 Bean 初始化前后执行自定义逻辑public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName);Object postProcessAfterInitialization(Object bean, String beanName);}Componentpublic class MyBeanPostProcessor implements BeanPostProcessor {Overridepublic Object postProcessBeforeInitialization(Object bean, String name) {System.out.println(初始化前 name);return bean;}Overridepublic Object postProcessAfterInitialization(Object bean, String name) {System.out.println(初始化后 name);return bean;}}用途AOP代理 日志 自动注入2. BeanFactoryPostProcessor:在 Bean 实例化之前修改 Bean 定义public interface BeanFactoryPostProcessor {void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);}Componentpublic class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory factory) {System.out.println(修改Bean定义);}}用途修改Bean配置修改属性修改 BeanDefinition例如Spring读取配置文件| 区别 | BeanFactoryPostProcessor | BeanPostProcessor || ---- | ------------------------ | ----------------- || 执行时间 | Bean实例化之前 | Bean实例化之后 || 操作对象 | BeanDefinition | Bean实例 || 使用场景 | 修改配置 | 修改对象 |八. Additional Capabilities of the ApplicationContextAdditional → 额外的 / 附加的Capabilities → 功能 / 能力ApplicationContext → Spring 应用上下文IOC 容器1. spring有两个核心的容器| 容器 | 说明 || ------------------ | ----------- || BeanFactory | 最基础的 IOC 容器 || ApplicationContext | 功能更强大的容器 |ApplicationContext BeanFactory 更多功能ApplicationContext额外的功能:1. 国际化i18nApplicationContext 支持 国际化消息。applicationContext.getMessage(login.success, null, Locale.CHINA);2. 事件发布机制ApplicationContext 提供事件机制。ApplicationEventPublisher发布事件applicationContext.publishEvent(new UserRegisterEvent(user));监听事件EventListenerpublic void handle(UserRegisterEvent event){System.out.println(用户注册事件);}用涂:解耦系统模块3. 资源加载Resource LoadingResourceLoaderResource resource applicationContext.getResource(classpath:test.txt);可以读取classpath 文件URL文件系统4. AOP集成ApplicationContext 自动支持AOP代理 自动织入例如AspectTransactional背后依赖BeanPostProcessor自动代理创建器5. 自动BeanPostProcessor注册ApplicationContext 会自动注册BeanPostProcessorBeanFactoryPostProcessor

相关新闻