范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

还在curd吗?封装属于自己的SpringStarter

  什么是Starter
  Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件)进行自动配置。
  使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,Spring Boot就能自动扫描并加载相应的模块并设置默认值,做到开箱即用为什么使用Starter
  在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。
  如果我们将这些可独立于业务代码之外的功配置模块封装成一个个starter,并在starter中设置好默认值,复用的时候只需要将其在pom中引用依赖即可,Spring Boot为我们完成自动装配,做到开箱即用。Springboot自动配置
  SpringBoot中的starter是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,Spring Boot就能自动扫描各个jar包下classpath路径的spring.factories文件,加载自动配置类信息,加载相应的bean信息并启动相应的默认配置。
  Spring Boot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循"约定大于配置"的理念。
  大家可以看看我之前写的一篇文章,详细介绍了springboot自动配置的流程:一文搞懂SpringBoot自动配置原理 - 掘金 (juejin.cn)spring.factories
  Spring Boot会默认扫描跟启动类平级的包,如果我们的Starter跟启动类不在同一个主包下,需要通过配置spring.factories文件来配置生效,SpringBoot默认加载各个jar包下classpath路径的spring.factories文件,配置的key为org.springframework.boot.autoconfigure.EnableAutoConfigurationStarter开发常用注解
  注解使用已经大大方便我们开发,再也不需要写xml配置文件了,SpringBoot经过查找spring.factories文件,加载自动配置类,而自动配置类中定义了各种运行时判断条件,如@ConditionalOnMissingBean(A.class)等,只要ioc容器中没有指定的A类型的bean信息,该配置文件才会生效。
  @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。属性映射注解@ConfigurationProperties :配置文件属性值和实体类的映射@EnableConfigurationProperties:和@ConfigurationProperties配合使用,把@ConfigurationProperties修饰的类加入ioc容器。配置bean注解@Configuration :标识该类为配置类,并把该类注入ioc容器@Bean :一般在方法上使用,声明一个bean,bean名称默认是方法名称,类型为返回值。条件注解@Conditional:是根据条件类创建特定的Bean,条件类需要实现Condition接口,并重写matches接口来构造判断条件。@ConditionalOnBean :容器中存在指定bean,才会实例化一个Bean@ConditionalOnMissingBean:容器中不存在指定bean,才会实例化一个Bean@ConditionalOnClass:系统中有指定类,才会实例化一个Bean@ConditionalOnMissingClass:系统中没有指定类,才会实例化一个Bean@ConditionalOnExpression:当SpEl表达式为true的时候,才会实例化一个Bean@AutoConfigureAfter :在某个bean完成自动配置后实例化这个bean@AutoConfigureBefore :在某个bean完成自动配置前实例化这个bean@ConditionalOnJava :系统中版本是否符合要求@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化@ConditionalOnResource:类路径下是否存在指定资源文件@ConditionalOnWebApplication:是web应用@ConditionalOnNotWebApplication:不是web应用@ConditionalOnJndi:JNDI指定存在项@ConditionalOnProperty: 配置Configuration的加载规则prefix :配置属性名称的前缀value :数组,获取对应property名称的值,与name不可同时使用name :数组,可与prefix组合使用,组成完整的配置属性名称,与value不可同时使用havingValue :比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置matchIfMissing :缺少该配置属性时是否可以加载。如果为true,没有该配置属性时也会正常加载;反之则不会生效Full全模式和Lite轻量级模式@Configuration参数proxyBeanMethods:Full 全模式(默认):@Configuration(proxyBeanMethods = true) 同一配置类下,当直接调用@Bean修饰的方法注入的对象,则调用该方法会被代理,从ioc容器中取bean实列,所以实列是一样的。即单实例对象,在该模式下SpringBoot每次启动都会判断检查容器中是否存在该组件Lite 轻量级模式:@Configuration(proxyBeanMethods = false) 同一配置类下,当直接调用@Bean修饰的方法注入的对象,则调用该方法不会被代理,相当于直接调用一个普通方法,会有构造方法,但是没有bean的生命周期,返回的是不同的实例。注:proxyBeanMethods 是为了让使用@Bean注解的方法被代理。而不是@Bean的单例多例的设置参数。测试例子这里不展示,可以下载我的代码查看@Configuration(proxyBeanMethods = false) public class AppConfig {          //放一份myBean到ioc容器     @Bean     public Mybean myBean() {         return new Mybean();     }      //放一份yourBean到ioc容器     @Bean     public YourBean yourBean() {         System.out.println("==========");         //注意:@Configuration(proxyBeanMethods = false):myBean()方法不代理,直接调用         //注意:@Configuration(proxyBeanMethods = true):myBean()方法代理,从ioc容器拿         return new YourBean(myBean());     } }
  什么时候用Full全模式,什么时候用Lite轻量级模式?当在你的同一个Configuration配置类中,注入到容器中的bean实例之间有依赖关系时,建议使用Full全模式当在你的同一个Configuration配置类中,注入到容器中的bean实例之间没有依赖关系时,建议使用Lite轻量级模式,以提高springboot的启动速度和性能Starter命名规范Spring官方Starter通常命名为spring-boot-starter-{name}如:spring-boot-starter-webSpring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式:如mybatis-spring-boot-starter。开发Starter1. 创建Starter项目
  新建项目后,要删除main启动类2. 添加依赖<?xml version="1.0" encoding="UTF-8"?>               org.springframework.boot         spring-boot-starter-parent         2.6.1                     4.0.0     com.ljw     ljw-spring-boot-starter     1.0                  1.8         8         8                                   org.springframework.boot             spring-boot-starter                                         org.springframework.boot             spring-boot-autoconfigure                                         org.springframework.boot             spring-boot-configuration-processor             true                 我们没有main入口,需要去除pom文件中maven打包插件spring-boot-maven-pluginspring-boot-configuration-processor作用:spring-boot-configuration-processor其实是一个注解处理器,在编译阶段干活的,一般在maven的声明都是optional 为true你在idea里面可以点击port,进到这个字段里面,还可以看到配置的提示信息这是因为在你的资源文件里面有一个spring-configuration-metadata.json文件,这是spring配置的元数据,是json形式3. 编写属性类
  @ConfigurationProperties可以定义一个配置信息类,和配置文件进行映射@ConfigurationProperties(prefix = "ljw.config") public class HelloProperties {      private String name = "hello 默认值!";      private int age = 8;      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     } }4. 自定义业务类
  这里可以模拟一些获取了配置文件信息的进行业务操作的业务类public class HelloService {      private String name;      private int age;      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public int getAge() {         return age;     }      public void setAge(int age) {         this.age = age;     }      public String hello() {         return "HelloService{" +                 "name="" + name + """ +                 ", age=" + age +                 "}";     } }5. 编写自动配置类
  命名规范:XxxAutoConfiguration@Configuration(proxyBeanMethods = false) // 当存在某个类时,此自动配置类才会生效 @ConditionalOnClass(value = {HelloService.class}) // 导入我们自定义的配置类,供当前类使用 @EnableConfigurationProperties(value = HelloProperties.class) // 只有非web应用程序时此自动配置类才会生效 @ConditionalOnWebApplication //判断ljw.config.flag的值是否为"true", matchIfMissing = true:没有该配置属性时也会正常加载 @ConditionalOnProperty(prefix = "ljw.config", name = "flag", havingValue = "true", matchIfMissing = true) public class HelloAutoConfiguration {      /**      * @param helloProperties 直接方法签名入参注入HelloProperties,也可以使用属性注入      * @return      */     @Bean     @ConditionalOnMissingBean(HelloService.class)     //@ConditionalOnProperty(prefix = "ljw.config", name = "flag", havingValue = "true", matchIfMissing = true)     public HelloService helloService(HelloProperties helloProperties) {         HelloService helloService = new HelloService();         //把获取的信息注入         helloService.setName(helloProperties.getName());         helloService.setAge(helloProperties.getAge());         return helloService;     }  }
  注:这里配置一个web应用才能注入,并且ljw.config.flag的值是否为"true"或者不配置该key才能注入HelloService服务6. 编写spring.factories
  把自动配置类HelloAutoConfiguration配置到org.springframework.boot.autoconfigure.EnableAutoConfiguration的key下,springboot会自动加载该文件并根据条件装配org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.ljw.starter.config.HelloAutoConfiguration7. 编写配置提示文件(非必须)additional-spring-configuration-metadata.json
  配置additional-spring-configuration-metadata.json文件后,在开发人员的IDE工具使用个人编写的配置读取很有效的在application.properties或application.yml文件下完成提示。
  配置详细格式参数可查看文档
  我的配置:{"properties": [     {       "name": "ljw.config.name",       "type": "java.lang.String",       "defaultValue": "hello 默认值!这里配置的是提示,真正默认值在Properties里面",       "description": "这是字符串名称啊."     },     {       "name": "ljw.config.age",       "defaultValue": 8,       "description": "这是int类型的年龄啊.",       "deprecation": {               "reason": "过时原因.",               "replacement": "替代key是:ljw.config.age22",               "level": "warning"             }     } ]}
  大家参考下面properties表格进行配置上的理解。
  名称
  类型
  目的
  name
  String
  属性的全名。名称采用小写的周期分隔形式(例如server.address)。此属性是强制性的。
  type
  String
  属性的数据类型的完整签名(例如java.lang.String),但也是完整的泛型类型(例如java.util.Map)。您可以使用此属性来指导用户可以输入的值的类型。为了保持一致性,通过使用其包装对应项(例如,boolean变为java.lang.Boolean)来指定基元的类型。请注意,此类可能是一个复杂类型,它从Stringas绑定的值转换而来。如果类型未知或基本类型,则可以省略。
  description
  String
  可以向用户显示的组的简短描述。如果没有可用的描述,则可以省略。建议描述为简短段落,第一行提供简明摘要。描述中的最后一行应以句点(.)结尾。
  sourceType
  String
  贡献此属性的源的类名称。例如,如果属性来自带注释的类@ConfigurationProperties,则此属性将包含该类的完全限定名称。如果源类型未知,则可以省略。
  defaultValue
  Object
  默认值,如果未指定属性,则使用该值。如果属性的类型是数组,则它可以是值数组。如果默认值未知,则可以省略。
  deprecation
  数组
  过时的描述。
  deprecation每个properties元素的属性中包含的JSON对象可以包含以下属性:
  名称
  类型
  目的
  level
  String
  弃用级别,可以是warning(默认)或error。当属性具有warning弃用级别时,它仍应绑定在环境中。但是,当它具有error弃用级别时,该属性不再受管理且不受约束。
  reason
  String
  该属性被弃用的原因的简短描述。如果没有可用的原因,可以省略。建议描述为简短段落,第一行提供简明摘要。描述中的最后一行应以句点(.)结尾。
  replacement
  String
  替换此不推荐使用的属性的属性的全名。如果此属性没有替换,则可以省略。spring-configuration-metadata.json
  spring-configuration-metadata.json代码量挺大的,为了方便我们可以通过IDE来生成,这里使用的是idea。
  在idea设置中搜索Annotation Processors,接下来勾住Enable annonation processing就完成了。 在编译打包后的文件中看到自动生成的spring-configuration-metadata.json。这个文件不用我们编写
  下面是自动生成的:{   "groups": [     {       "name": "ljw.config",       "type": "com.ljw.starter.properties.HelloProperties",       "sourceType": "com.ljw.starter.properties.HelloProperties"     }   ],   "properties": [     {       "name": "ljw.config.name",       "type": "java.lang.String",       "description": "这是字符串名称啊.",       "sourceType": "com.ljw.starter.properties.HelloProperties",       "defaultValue": "hello 默认值!这里配置的是提示,真正默认值在Properties里面"     },     {       "name": "ljw.config.age",       "type": "java.lang.Integer",       "description": "这是int类型的年龄啊.",       "sourceType": "com.ljw.starter.properties.HelloProperties",       "defaultValue": 8,       "deprecated": true,       "deprecation": {         "level": "warning",         "reason": "过时原因.",         "replacement": "替代key是:ljw.config.age22"       }     }   ],   "hints": [] }测试Starter1. 前置环境
  install打包自定义starter项目:ljw-spring-boot-starter
  新建项目:ljw-test-spring-boot-starter2. 添加依赖
  引入打好包的自定义starter                       org.springframework.boot         spring-boot-starter                        org.springframework.boot         spring-boot-starter-web                        com.ljw         ljw-spring-boot-starter         1.0      3. 测试类@Service public class TestController implements CommandLineRunner {      /**      * 注入自定义starter服务      */     @Resource     private HelloService helloService;      @Override     public void run(String... args) throws Exception {         System.out.println(helloService.hello());     } }4. 修改配置文件
  输入前缀可以看出已经有提示了
  ljw.config.name=ljw hello! ljw.config.age=99 ljw.config.flag=true #不会注入 #ljw.config.flag=true1 # 可以看到哪些自动配置了 debug=true5. 运行程序打印HelloService{name="ljw hello!", age=99}条件注入如果没有spring-boot-starter-web依赖,不能注入服务HelloService如果配置了ljw.config.flag,值不是true,不能注入服务HelloService;如果不配置ljw.config.flag,可以注入6. 查看自动配置类生效的方法
  通过启用 debug=true 属性,让控制台打印自动配置报告,这样就可以很方便地知道哪些自动配置类生效。   HelloAutoConfiguration matched:       - @ConditionalOnClass found required class "com.ljw.starter.service.HelloService" (OnClassCondition)       - @ConditionalOnWebApplication (required) found "session" scope (OnWebApplicationCondition)       - @ConditionalOnProperty (ljw.config.flag=true) matched (OnPropertyCondition)     HelloAutoConfiguration#helloService matched:       - @ConditionalOnMissingBean (types: com.ljw.starter.service.HelloService; SearchStrategy: all) did not find any beans (OnBeanCondition)
  作者:小伙子vae
  链接:https://juejin.cn/post/7047674475331977224

奈飞崩了,下一个是Meta?科技公司的高估值反映出了投资者对持续增长的信念,如今这种信念越来越像是一个神话,而不是现实。周二晚间,奈飞公司(Netflix)公布的2022一季度财报引发了这场生死攸关的危机。该马斯克回应特斯拉连续涨价4月21日凌晨,特斯拉汽车公布了该公司2022财年第一季度财报,同时马斯克也在特斯拉财报电话会议上回应了近期特斯拉频繁涨价的问题。马斯克表示,考虑到特斯拉本季度盈利创历史新高,提价一年亏损近500亿元,滴滴又有新动作?在这个互联网高度发达的时代里,许多与之相关的行业都得到了巨大的红利,比如网约车行业就是一个很好的例子。这些年来我国的网约车行业发展十分迅速,已经成为了很多国民们首选的出行方式。同样英媒文章中国将迎来一场创新革命英国经济学人周刊网站4月16日发表题为中国下一阶段创新的大胆规划的文章,全文摘编如下对湖南省株洲市来说,未来一片光明。在当地官员口中,这座城市仿佛是一个技术中心。过去一年,当地涌现计划失败了,华为5G传来捷报,欧洲各国可能要后悔了?自从5G技术被提出并且开始在全球大范围普及以后,各行各业都迎来了新的发展机遇。或许对于普通用户来讲,5G和4G的差别并不大,但对于一些技术来说,5G网络高带宽低延时的特性,能够让4京东pop店铺收费标准,有何基本要求?对于京东pop店铺不少新手卖家不怎么了解,这是属于第三方商家入驻京东,商家自己去运营店铺且推广,所以想要入驻京东pop店铺需要先了解它的收费标准,下面我们一起来了解清楚。京东POPvivo自研芯片V1双芯合璧,一芯二用今天,单独靠拼参数,已显得不适应。硬件很重要,但如何激发硬件潜力,离不开软实力,这才是手机厂商的核心能力,也决定了手机厂商的上限。在自研技术方面,vivo通过多年努力,已实现多点开常见的8个概率分布公式和可视化概率和统计知识是数据科学和机器学习的核心我们需要统计和概率知识来有效地收集审查分析数据。现实世界中有几个现象实例被认为是统计性质的(即天气数据销售数据财务数据等)。这意味着在某些情JVM从入门到放弃之ZGC垃圾收集器精讲ZGarbageCollector,也称为ZGC,在jdk11中引入的一种可扩展的低延迟垃圾收集器,在jdk15中发布稳定版。在旨在满足以下目标1ms最大暂停时间(jdk16是10Magic4Pro对比S22Ultra,摄影作品上期视频我们对比的是荣耀Magic4Pro和三星S22Ultra。链接如下荣耀Magic4Pro对比三星S22Ultra理想VS现实想了解这两台手机影像的朋友可以去看视频。以下是上小米发布2299元男性美颜手机性能不是重点中关村在线消息4月21日下午小米正式发布新机小米Civi1S,该款机型搭载了全新的男生自然美颜技术,该技术专为男生设计,可以实现不失棱角的美颜效果,同时做到光影质感恰到好处,还原自
车子好不好,试试才知道,买车时的4大错误观念,你中了几个?很多朋友买车之前都会先查查口碑,然后听听周边人的建议定购某款车。貌似都挺合理,但是却忽视了自己的体验感受。其实不管买什么,自己去体验好过一切的听闻。毕竟在选购汽车方面,每个人的喜好车前脸撞烂了算大事故吗?只要不伤及这两块部件,基本都不算什么随着经济的增长,城市化进程加快,道路变得越来越拥堵。开车出行难免会发生一些交通事故,轻则刮擦,重则车辆报废。其实事故后的车辆有时候看起来损坏很严重,其实并不算大事故,相反,有些看起开车出了事故,认定对方全责,对方拖着不解决怎么办?每天三分钟,用车更轻松!大家好,我是你们的好朋友木沐阳。开车出了事故,不管责任在于谁,都是个烦心事。如果已经认定对方全责,但是对方拖着不解决,那这更是雪上加霜。这种人就是典型的老赖车子开多久卖掉最划算?5年10年15年,还是开到报废?根据机动车强制报废标准规定第七条,对达到一定行驶里程的机动车引导报废,小微型汽车是行驶60万千米。按家庭乘用车平均每年正常行驶里程1。5万公里为标准计算,需要开40年才达到国家引导开10万以内的车子丢人吗?那些说三道四的人,麻烦闭嘴好吗为什么说这个话题,是因为逛论坛的时候看到有人说开10万以内的车子就是垃圾。这社会进步了,那些口吐莲花的人也能敲着键盘充当大侠了。不得不说,有这样的三观,要么家里有矿,要么脑袋有问题15条城市道路驾驶经验,满满干货,学会可有效减少事故的发生1去路不熟的地方,为避免出错,最好提前规划路线并了解路况(不要盲从导航)。没做功课的话,可以停下来问问路人,不要害羞。2经过路口时,如果左右两边被并行的其他车挡住了视线,不要加速冒汽车除积碳,哪种方式最有效?最后那种方法,老司机都推荐积碳,相信有些汽车知识的朋友都知道。简单科普下,汽油中的一些不饱和烃成分在一定的温度下,容易与空气发生氧化反应和聚合反应,反应生成一种胶质状的化学物质,这些化学物质通过燃油系统输送新车速递2021年上海车展,多款重磅新车,1场宏大的汽车盛宴每天三分钟,用车更轻松!大家好,我是你们的好朋友木沐阳。2021年上海车展可谓是万众瞩目,为什么这么说呢?因为疫情的影响,国外A级车展无一例外都被迫取消,所以如期举办的上海车展就更第11代全新本田思域海外版发布,外观酷似雅阁,内饰是一大亮点每天三分钟,用车更轻松!大家好,我是你们的好朋友木沐阳。北京时间4月29日,本田在美国发布了全新一代的思域,这是本田思域家族第十一代车型。整车外形向雅阁靠拢,腰线由车头贯穿至车尾,自吸车很多人喜欢,为什么最后都买了涡轮增压?其实原因很简单如果提到发动机技术,那么自然吸气和涡轮增压发动机技术绝对是一个回避不了的热门话题。选自然吸气还是涡轮增压,很多人都有自己的评判。自然吸气发动机发展时间长,技术成熟,其内部构造相对简清洗节气门很简单,但若你用错了方法,油耗飙升也是常有的事节气门相当于发动机的咽喉,发动机工作所需要的空气就是由节气门控制。在节气门的上端接着空气滤清器,下端连着发动机缸体,整个进气量都是需要经过节气门的调节才能使发动机正常运转。发动机工