大家好,关于springboot常用10个注解很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于java注解是怎么实现的的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
springboot 注解与程序的区别
springboot注解是注册解释,程序是有程序的
springboot和springcolud的区别
SpringBoot与SpringCloud的关系与区别
一、SpringBoot和SpringCloud简介
1、SpringBoot:是一个快速开发框架,通过用MAVEN依赖的继承方式,帮助我们快速整合第三方常用框架,完全采用注解化(使用注解方式启动SpringMVC),简化XML配置,内置HTTP服务器(Tomcat,Jetty),最终以Java应用程序进行执行。
2、SpringCloud:是一套目前完整的微服务框架,它是是一系列框架的有序集合。它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过SpringBoot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。它利用SpringBoot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用SpringBoot的开发风格做到一键启动和部署。
二、SpringBoot和SpringCloud的关系与区别
1、SpringBoot只是一个快速开发框架,使用注解简化了xml配置,内置了Servlet容器,以Java应用程序进行执行。
2、SpringCloud是一系列框架的集合,可以包含SpringBoot。
三、SpringBoot是微服务框架吗?
1、SpringBoot只是一个快速开发框架,算不上微服务框架。
2、SpringCloud+SpringBoot实现微服务开发。具体的来说是,SpringCloud具备微服务开发的核心技术:RPC远程调用技术;SpringBoot的web组件默认集成了SpringMVC,可以实现HTTP+JSON的轻量级传输,编写微服务接口,所以SpringCloud依赖SpringBoot框架实现微服务开发。
四、SpringMVC在3.0开始支持采用注解方式启动,所以可以不再配置传统的XML配置文件。
springbootmain方法启动注解的区别
那要看你使用的是自动加载获取spring上下文还是手动加载获取spring上下文,如果是手动用编码方式加载spring的xml配置文件,那就可以用main里面运行,要是使用服务器已启动时自动加载spring配置文件,那就不能使用main方法了,呼呼
SpringBoot中,@Autowired和@Resource使用起来到底有什么区别
这个问题也有一段时间了,当初也就随手一写,直到最近还有网友在看,为了保证大家看的时候不会出现理解方面的问题,于2021-5-10编辑一次,希望能更加严谨一点,至少不会误导大家。
首先,这个问题有点不准确,这2个注解是使用Spring框架过程中常用的注解,而SpringMVC和SpringBoot等框架都是基于Spring的进阶框架,并没有对这2个注解的使用进行修改或者调整,所以,只讨论Spring框架如何处理这2个注解即可,而不是讨论在SpringBoot中的使用区别。
【结论】在绝大部分情况下,使用这2个注解的任何一个都可以实现自动装配,在使用方面是无感的。
如果要讨论区别,基本上就是2点:
所属不同:@Resource注解是javax包的;@Autowired是Spring声明的;装配机制不同:@Resource会优先byName来装配,即使名称不匹配,也会尝试byType来装配;@Autowired则是先查找匹配类型对象的数量,如果有且仅有1个,则直接装配,如果为0个,则无法装配,此时需要考虑该注解的required属性,默认是true,就会因为“必须装配却没有匹配类型的对象”而抛出异常,如果显式的设置为false,则不装配,保持被自动装配的属性为null值,如果匹配类型的对象超过1个,则会尝试byName,如果成功,则装配,如果失败,则抛出异常。如果一定要说还有其它区别,可以是:
作用范围不同:@Resource用于对字段、Setter方法进行注解,@Autowired可用于构造方法、Setter方法和字段;当同一种类型的对象有多个时(例如声明的类型是接口,在Spring容器中有2个或多个实现类的对象),需要指定名称,@Resource可直接配置name属性来指定bean-name,而@Autowired需要配合@Qualifer注解,由@Qualifer注解来指定bean-name,当用于字段时,直接在字段的声明之前使用这2个注解,当用于Setter方法时,在方法的声明之前使用@Autowired,在方法的参数之前使用@Qualifer;另外,还有很多关于使用@Autowired的细节问题,例如“是不是不建议使用了”、“到底应该怎么用”等等,所以,接下来主要讨论这些问题。
关于“是不是不建议使用了”,这种问题的主要原因应该是最近几年IntelliJIDEA越来越流行了,而许多版本的IntelliJIDEA对@Autowired的预判是有问题的!也就是说:IntelliJIDEA会在编码期实时预判是否存在可以装配的对象,如果它认为没有,就会报错,事实上,它的判断并不完全准确!
例如,尝试在Service组件中装配一个Mapper接口类型的字段时:
(截图来自IntelliJIDEA2020.1.4)
以上报错就是IntelliJIDEA预判错误导致的,如果使用的是Eclipse就不会有这样的问题,解决方案可以是:
在UserMapper接口上添加@Repository注解;将以上代码中的@Autowired配置为@Autowired(required=false),因为@Autowired默认是required=true,同时IntelliJIDEA认为没有可装配对象,所以报错,显式的配置为required=false之后,即使IntelliJIDEA认为没有可装配对象也不会报错了;将以上代码中的@Autowired改为@Resource。再例如在使用SpringSecurity进行配置时也会有类似的问题,只不过这次它认为“存在多个匹配类型的对象”:
(截图来自IntelliJIDEA2020.1.4)
解决以上报错信息的方式可以是:
将声明的UserDetailsService接口类型改为你的UserDetailsServiceImpl实现类类型,例如privateUserDetailsServerImplservice;即可;将以上代码中的@Autowired改为@Resource。由于许多类似问题都可以通过“将@Autowired改为@Resource”来解决,加上一些相关说法(详见下文),且某些片面的断章取义,导致网上还存在“使用@Resource取代@Autowired”、“以后不要再用@Autowired”的说法,而这些说法都是错误的,没有任何官方(开发工具的IntelliJIDEA,或框架官方Spring)说过这样的话!
首先,使用Spring实现自动装配时,有3种方式:
通过构造方法注入;通过Setter注入(即与字段属性匹配的set方法);通过字段注入;基本示例参见下图:
以上图片来自Spring官方提供的资料,可以看到最后还附了个URL,是国外网友写的一篇主题为《whyfieldinjectionisevil》的讨论文章,有兴趣且有一定英语阅读能力的朋友可以自行上网查看全文,大意是“使用字段注入时可能导致NPE”!为什么会这样呢?假设你有如下代码:
如果你因为某种原因直接创建对象,即通过UserServiceservice=newUserService();来创建对象,其中的userRepository属性肯定是没有值的,后续使用这个service对象时,只要涉及调用userRepository就会出现NPE了!
既然UserService是一个组件,为什么还会直接创建对象呢?其实这也算是一个低概率的特殊情况,在彼此不太熟悉的协同工作中可能出现,例如你和我一起开发项目,我对你写的那部分代码不太了解……再就是测试使用时,也可能出现直接创建对象的情况……
如果将代码改为下面这样:
则刚才的问题就不存在了!因为现在的构造方法是需要参数的,你不给参数,就创建不了对象!如果能创建出对象,就肯定给了参数,则userRepository肯定有值,就不会出现NPE!当然,如果你一定要传个null进去就没办法了,Nozuonodiewhyyoutry?
所以,使用构造方法传递参数是一种强制依赖的做法,可以保证不会出现NPE,但是,如果参数太多会不会很奇怪?真的有必要把代码写得这么滴水不漏吗?这个就看你自己了!首先,是IntelliJIDEA并不建议你使用字段注入:
(截图来自IntelliJIDEA2020.1.4)
而Spring的观点,可参见下图:
可以看到,Spring是无所谓的,反正都能用(Springdoesn'tcare,canuseeither),当然,也列举了使用构造方法注入和使用Setter注入的区别(虽然我在前面都是写的字段注入,在NPE问题上,字段注入和Setter注入是一样的)。
既然Spring都无所谓了,我们为什么还要纠结注入方式呢?还是那句话,只要你能保证不出错,怎么都行!可能95%以上的Java从业者不是在写大厂的大型项目,合格的程序员也不会乱写代码,由Setter或字段注入导致NPE的概率本来就极低,不一定需要为了“保证极端情况下也不出错”而刻意的把代码调整为构造方法注入,只要注意规避这个问题即可!
另外,我在上面的代码演示中,在构造方法上加了@Autowired注解,在这里解释一下:
如果类中只存在默认构造方法(无论是你显式的添加的,还是根本不写,由编译器添加的),则无需@Autowired注解,Spring会自动调用,当然,加了也不会出错;如果类中只存在唯一的构造方法,Spring会自动调用,且会自动从Spring容器中找对象装配为调用构造方法的参数,这种情况也是不需要添加@Autowired注解的,加了也不会出错;如果类中存在多个构造方法,且都没有添加@Autowired注解时,当存在无参数构造方法时,Spring会自动调用无参数构造方法,如果你想要Spring调用另外某一个构造方法,就在那个构造方法上添加@Autowired注解;如果类中存在多个构造方法,且超过1个构造方法上都添加了@Autowired注解……你别作,你不需要知道Spring怎么处理,你只要把@Autowired删得只有1个了,就肯定没问题!所以,从道理上来说,应该推荐显式的为某1个构造方法添加@Autowired注解,哪怕是不需要添加也能用,因为这样会保证多构造方法的情况下代码更加直观,增加代码的可读性,但是,从实际工作出发,可能就变成了“有啥好加的?这点道理都不懂还上什么班?”……大家都懒得加了,所以,又不是什么很难懂的原理,加不加就自行把握吧。
最后,再总结一下使用原则:
@Autowired和@Resource在使用时可以不纠结它们的区别,使用它们的目的就是为了装配对象,只要能装得上,装的是对的,无所谓使用哪个?一定要区分选取,先保证“在同一个项目中使用同一个”,不要一个类使用@Autowired,另一个类又使用@Resource,然后,我个人建议使用@Autowired,原因嘛,很简单,你既然用Spring框架,就用它带的注解呗;关于@Autowired的使用方式,不怕麻烦就都使用构造方法注入,且显式的添加@Autowired,如果怕麻烦,只要不出错,就随意吧。Spring官方也考虑到了网友关于@Resource或相关注解的问题,因为没什么需要特别解释的了,就直接贴图好了,大家自行查阅,以下图片仍是来自Spring官方资料:
最后,近期因为工作的关系看了不少Spring的官方资料,包括官方的Spring学习教程,有些感慨,给我的感觉,Spring对外提倡实用主义,极少和你讲理论,源码什么的更是少得可怜,这也和面向对象的思想保持一致,人家都帮你做好了,你好好用就行了,不必关心实现细节,希望大家也能这样!现在IT行业真的被一些大厂带节奏了,网上各种吸引眼球的XX源码解析、XX底层原理、XX加载过程分析、XX算法、大厂案例、大厂面试题……很多时候真的想喷一句“你咋不从操作系统开始做软件研发呢”……真的,绝大部分Java从业者一辈子都进不了大厂,也接触不到超过20台以上服务器才能扛得住的项目,除非是为了应付面试,你甚至不需要知道i++和++i的区别,如果只是自己写代码自己用,你也不需要知道private和public的区别……如果你只想开自己的私家车,不想修车也不想造车,除了吹牛,你都不需要知道发动机的型号……多掌握实用技术,多积累解决问题的经验,原理什么的能不管就不要管,当熟练到一定程度后,再考虑要不要深入了解原理。
好了,就这么多,如果有错别字,大家将就一下吧(可编辑次数有限),如果有觉得不对的地方,欢迎留言讨论。
自定义的Spring Boot starter如何设置自动配置注解
在了解如何设置自动配置注解之前可以先看看spring-boot的自动配置原理,了解了原理之后,在来看如何配置就很简单了;
SpringBoot自动配置
1.自动配置注解
要想使用自动配置功能,SpringBoot提供了注解@EnableAutoConfiguration,当然不需要我们配置因为在@SpringBootApplication注解中默认以及启用了;
可以看到@SpringBootApplication注解本身也有注解@EnableAutoConfiguration:
在注解@EnableAutoConfiguration中重点看一下@Import注解中使用的AutoConfigurationImportSelector类,此类是自动注解的核心类,会有条件的加载我们默认指定的配置类;这里有两个概念一个是有条件,一个是配置类,分别简单介绍一下:配置类可以简单理解就是相关组件对接SpringBoot的对接类,此类可以做一些初始化的工作;有条件表示并不是有配置类就能被对接上,是有条件的,SpringBoot默认提供了大量配置类,但并不是所有配置类都能被加载初始化的,是有条件的,比如mybatis在没有数据源的情况下,没有mybatis基础包的情况下是不能被对接的;下面首先看一下SpringBoot提供的哪些条件类;
2.条件类
SpringBoot提供了很多条件类,可以在配置中上配置注解条件类,相关条件类可以在spring-boot-autoconfigure包下的org.springframework.boot.autoconfigure.condition下找到,主要包含如下:
ConditionalOnBean:当前容器有指定Bean的条件下;ConditionalOnClass:当前类路径下有指定类的条件下;ConditionalOnCloudPlatform:当指定了云平台的时候;ConditionalOnExpression:SpEL表达式作为判断条件;ConditionalOnJava:JVM版本作为判断条件;ConditionalOnJndi:在JNDI存在的条件下查找指定的位置;ConditionalOnMissingBean:当容器里没有指定Bean的情况下;ConditionalOnMissingClass:当类路径下没有指定的类的条件下;ConditionalOnNotWebApplication:当前项目不是WEB项目的条件下;ConditionalOnProperty:当前应用是否配置了指定属性指定的值;ConditionalOnResource:只有当指定的资源位于类路径下;ConditionalOnSingleCandidate:bean工厂中只有一个或者有多个情况下是主要的候选bean;ConditionalOnWebApplication:当前项目是WEB项目的条件下。以上是注解类,注解本身没有功能,只是提供标记的功能,具体功能在@Conditional中指定的,比如ConditionalOnBean注解如下所示:
相关功能的实现就在OnBeanCondition类中,同样其他注解类的实现类也在包org.springframework.boot.autoconfigure.condition下找到;
3.自动配置过程
Springboot应用启动过程中使用ConfigurationClassParser分析配置类,此类中有一个processImports方法,此方法用来处理@Import注解,在@EnableAutoConfiguration注解存在@Import注解,这时候会实例化注解中的AutoConfigurationImportSelector,在其内部有一个AutoConfigurationGroup内部类,内部类有两个核心方法分别是:process和selectImports;
此方法主要获取经过条件过滤之后可用的自动配置类,主要调用AutoConfigurationImportSelector中的getAutoConfigurationEntry完成的:
首先获取了所有备选的自动配置类,然后删除了重复和被排除的类,最后通过条件进行筛选出可用的配置类,下面分别看一下,首先看一下如何获取所有备选的配置类:
通过SpringFactoriesLoader获取类路径下META-INF/spring.factories文件中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置类,可以看一下spring-boot-autoconfigure.jar中的spring.factories内容:
当然这里只是截取了其中一个类路径jar下的部分配置,获取所有配置类之后进行去重,去被排除的类,然后进行条件过滤,下面重点看一下:
此方法大致就是首先获取配置的AutoConfigurationImportFilter,然后对之前获取的所有配置类进行过滤,最后返回过滤之后的配置类;AutoConfigurationImportFilter同样也是通过SpringFactoriesLoader类进行加载类路径下META-INF/spring.factories,只不过当前的key是:org.springframework.boot.autoconfigure.AutoConfigurationImportFilter,可以看一下SpringBoot默认配置的filter:
可以看到Filter其实就是上文介绍的条件类,这里默认了OnBeanCondition,OnClassCondition以及OnWebApplicationCondition,已这里使用的Mybatis为例看一下MybatisAutoConfiguration的注解:
可以看到其中有用到@ConditionalOnClass,表示必须提供SqlSessionFactory和SqlSessionFactoryBean类的情况下才加载此配置类,而整两个是正式Mybatis基础包中提供的;有了基础包还不行,还需要DataSource,而且DataSource必须在MybatisAutoConfiguration实例化之前初始化好,SpringBoot是如何实现,继续看另外一个核心方法selectImports():
首先是对被排除类的一个过滤,然后接下来重点看一下对配置类进行排序的一个方法,具体操作在类AutoConfigurationSorter中进行的,具体方法为getInPriorityOrder():
首先使用order进行排序,然后使用@AutoConfigureBefore和@AutoConfigureAfter就行排序;order其实就是通过注解@AutoConfigureOrder进行排序的,值是一个整数,结构类似如下:
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE+10)@AutoConfigureBefore和@AutoConfigureAfter字面意思也很好理解,指定在其他配置类之前和之后,所以可以看到在MybatisAutoConfiguration中有如下配置:
表示在DataSourceAutoConfiguration配置类加载之后才会加载Mybatis配置类,这样就解决了依赖关系;还有上文提到的Mybatis操作数据库依赖的SqlSessionFactory和SqlSession,都在MybatisAutoConfiguration进行了初始化操作;SpringBoot本身其实以及提供了大量常用组件的自动配置类,我们只需要提供满足的特定条件,SpringBoot自动会帮我加载初始化等操作;
下面用一个简单的实例来看看如何自定义一个自动配置类;
自定义配置类
接下来我们用很简单的实例来看一下自定义的流程,一个格式化大写消息的实例;
1.pom文件引入依赖
Spring官方Starter通常命名为spring-boot-starter-{name}如spring-boot-starter-web,Spring官方建议非官方Starter命名应遵循{name}-spring-boot-starter的格式;
2.服务类和属性配置类
属性类提供了type参数可以在application.properties中配置,可配置值包括:upper,lower;
3.自动配置类和创建spring.factories文件
这个就是自定义的自动配置类,SpringBoot启动的时候会根据条件自动初始化;最后在resources/META-INF/下创建spring.factories文件:
4.测试
在其他SpringBoot中可以引入上面创建的项目,引入方式也很简单:
同时在application.properties配置格式化类型:
启动应用,浏览器访问http://localhost:8888/format?word=hello,结果为:HELLO
以上分析了一下springboot的自动配置原理,并自定义一个自动配置类,并且运行,相信对你有所帮助;
更多可以参考本人之前的文章:https://www.toutiao.com/i6749752249532023309/
好了,文章到这里就结束啦,如果本次分享的springboot常用10个注解和java注解是怎么实现的问题对您有所帮助,还望关注下本站哦!