@order注解是spring-core包下的一个注解,@Order的作用是定义Spring IOC容器中Bean的执行顺序的优先级(这里的顺序也可以理解为存放到容器中的先后顺序)。开发过程当中有时候经常会出现配置依赖关系,例如注入A对象使用了@ConditionalOnBean(B.class),意思是要求容器当中必须存在B.class的实例的时候,才会进行注入A。这时候我们就必须保证B对象在注入A对象前进行注入。
目录
(1)源码当中有三个元注解:
(2)属性:
@order当中只要一个value属性,而且还是int类型,值越低优先级越高,默认值是Ordered.LOWEST_PRECEDENCE,表示最低优先级(输给任何其他指定的顺序值)。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
int value() default 2147483647;
}
(1)自定义两个配置类
我们要求Config2先进行加载,然后通过@order来排序测试一下
@Configuration
public class Config1 {
public Config1() {
System.out.println("Config1构建了");
}
}
@Configuration
public class Config2 {
public Config2() {
System.out.println("Config2构建了");
}
}
(2)启动项目测试:默认是先创建的Config1后创建的Config2

(3)既然order可以控制加载顺序,那我们来试验一下,然后让Config2 先加载
@Configuration
@Order(2)
public class Config1 {
public Config1() {
System.out.println("Config1构建了");
}
}
@Configuration
@Order(1)
public class Config2 {
public Config2() {
System.out.println("Config2构建了");
}
}
但是好像没什么卵用

(4)分析原因
目前这两个是在同包情况下不起作用。

于是进行分开了

分开之后竟然生效了

(5)但是分开也是将Config2放到了上面的包当中,于是我又改成了Config1放到最上面,这样进行测试,结果又失效了


(6)于是我又放在了同包下,将Config2命名为A开头的,这样他就放到了最上面,于是这样同样也生效了。


期间我还尝试着将@Configuration都改为使用@Component,结果仍然不变。
得出结论:
@order指定加载顺序还跟类的命名和存放位置有关!假如有Config1和Config2两个类在一个包下,要求是Config2先加载:
Config2的@order值就算是小于Config1的@order值同样也是Config1先加载。这样才能保证@Order生效!

最关键的一句话:您可以在目标类级别和@Bean方法上声明@Order注释,可能针对的是单个bean定义(如果多个定义使用同一个bean类)。@Order值可能会影响注入点的优先级,但请注意,它们不会影响单例启动顺序,这是由依赖关系和@DependsOn声明确定的正交关注。
我理解的注入点的优先级应该是指的存放容器的先后顺序,也就是他并不会影响启动顺序。
我们不可能每次遇到这种问题又是改名又是换包的,所以,springboot提供了如下三个注解可以控制顺序:
(1)首先将代码改回原来的样子

(2)在Config2使用@AutoConfigureBefore(Config1.class),代表的是在config1加载前进行加载
@Configuration
public class Config1 {
public Config1() {
System.out.println("Config1构建了");
}
}
@Configuration
@AutoConfigureBefore(Config1.class)
public class Config2 {
public Config2() {
System.out.println("Config2构建了");
}
}
(3)输出结果,显然还是没生效

可能有时候走了狗屎运给你一种错觉还真的配置成功了。实际上这种方式是不可行的,以上三个注解只有针对
自动配置类才会生效。
在autoconfigure包下就有spring.factories,这个文件配置了自动配置类,springboot会读取这个文件的,我们也可以在自己项目上定义spring.factories,这样我们的配置类对于@AutoConfigureAfter注解就可以生效了。

(4)自定义spring.factories

第一行是固定的,后面的就是全类名,虽然只有Config2使用了注解,但是需求是和Config1进行排序,所以这两个都得加。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gzl.cn.springbootcache.config.Config2,\
com.gzl.cn.springbootcache.config.Config1
(5)测试,成功解决

针对于@AutoConfigure那三个注解原理:其实关键的代码还是在AutoConfigurationImportSelector中,将自动配置类从spring.factories加载出来之后会根据条件排序(只有自动配置类!),在selectImports()方法中最后一行代码如下:

紧接着会走到这个地方,实际上是分了三步排序:

从上面配置的顺序可以知道,最终决定权还是在@AutoConfigureAfter、@AutoConfigureBefore这两个注解。
当我们不设置spring.factories的时候,这里面压根都没有这两个类!

这种也是可以的!当然前提也是需要配置spring.factories
@Configuration
@AutoConfigureOrder(2)
public class Config1 {
public Config1() {
System.out.println("Config1构建了");
}
}
@Configuration
@AutoConfigureOrder(1)
public class Config2 {
public Config2() {
System.out.println("Config2构建了");
}
}
在我的Controller中,我得到了按类别分组的所有Extras:defindex@categories=Extra.all.group_by(&:category)end结果类似于哈希数组:{#=>[#,#=>[#,#]}我想按类别“排序”列而不是id排序,它应该如下所示:{#=>[#,#=>[#,#]}当我尝试时:defindex@categories=Extra.all.group_by(&:category).sort_by{|s|s[:sort]}end我得到“没有将符号隐式转换为整数”。那是因为我在“sort_by”中使用了一个符号吗? 最佳答
在Ruby(或Rails)中,我们可以做到new_params=params.merge({:order=>'asc'})现在new_params是一个带有添加键:order的散列。但是是否有一行可以返回带有已删除key的散列?线路new_params=params.delete(:order)不会工作,因为delete方法返回值,仅此而已。我们必须分3步完成吗?tmp_params=paramstmp_params.delete(:order)returntmp_params有没有更好的方法?因为我想做一个new_params=(params[:order].blank?||para
我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有
我在尝试使用Faraday将文件上传到网络服务时遇到问题。我的代码:conn=Faraday.new('http://myapi')do|f|f.request:multipartendpayload={:file=>Faraday::UploadIO.new('...','image/jpeg')}conn.post('/',payload)尝试发布后似乎没有任何反应。当我检查响应时this是我所看到的:#:post,:body=>#,#,@opts={}>,#],@index=0>>,#>],@ios=[#,#,@opts={}>,#],@index=0>,#],@index=0>
我使用raise(ConfigurationError.new(msg))引发错误我试着用rspec测试一下:expect{Base.configuration.username}.toraise_error(ConfigurationError,message)但这行不通。我该如何测试呢?目标是匹配message。 最佳答案 您可以使用正则表达式匹配错误消息:it{expect{Foo.bar}.toraise_error(NoMethodError,/private/)}这将检查NoMethodError是否由privateme
我有一个以时间戳为键的哈希。hash={"2016-05-31T22:30:58+02:00"=>{"path"=>"/","method"=>"GET"},"2016-05-31T22:31:23+02:00"=>{"path"=>"/tour","method"=>"GET"},"2016-05-31T22:31:05+02:00"=>{"path"=>"/contact_us","method"=>"GET"}}我订购了这个系列并得到了第一双这样的:hash.sort_by{|k,_|k}.first.first但是我该如何删除它呢?删除方法requiresyou知道key的准确
目录ChatGPT简介技术原理应用未来发展ChatGPT的10 种用法ChatGPT简介ChatGPT是一种基于深度学习的大型语言模型,由OpenAI公司开发。技术原理GPT是GenerativePre-trainedTransformer的缩写,意为生成式预训练变压器。它的技术原理是使用了一个基于注意力机制的变压器(Trans
我找不到任何使用Rack::Session::Cookie的简单示例,并且希望能够将信息存储在cookie中,并在以后的请求中访问它并让它过期.这些是我能找到的唯一示例:HowdoIset/getsessionvarsinaRackapp?http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html这是我得到的:useRack::Session::Cookie,:key=>'rack.session',:domain=>'foo.com',:path=>'/',:expire_after=>2592000,:secret=
我是Ruby的新手,发现以下几对令人困惑示例同样有效:File.included_modulesFile::included_modulesFile.stat('mbox')#Returnsa'#'objectFile::stat('mbox')File.new("foo.txt","w")File::new("foo.txt","w")"asdf".size#Aninstancemethod"asdf"::size2+32::send(:+,3)#AnextremeexampleFile::new,尤其是我经常遇到的东西。我的问题:如果我永远避免使用::运算符来限定除类、模块和常量之
如果数组只包含一个值,我想返回数组的第一个元素。目前,我使用:vals.one??vals.first:vals.presence因此:vals=[];vals.one??vals.first:vals.presence#=>nilvals=[2];vals.one??vals.first:vals.presence#=>2vals=[2,'Z'];vals.one??vals.first:vals.presence#=>[2,"Z"]是否有内置的东西可以做到这一点,或者是否有更好的设计考虑?我的用例是特定的,涉及知道从方法(将实现上述代码)中期望什么的演示者。如果这些演示者将所有返回