一,是否使用@Bean注解的区别
1.问题发现
一直有个疑问,都知道使用@Bean将对象或者方法教给Spring管理,但实际使用过程中,发现如果单纯调用一个对象后者方法时,不使用@Bean注解也能调用,那么Spring如何体现对对象的管理呢?
这里,加不加@Bean在这个类中都能正常使用。
2.问题分析
在上述地方加一个输出
添加@Bean ,在页面多刷新几次,后台结果如下:
由此可见,使用@Bean注解时,无论页面刷新多少次(即doRestEcho1方法执行了多少次),添加注解的方法只在一开始(在页面刷新前)执行了一次,之后就不会再执行。
不添加@Bean ,在页面多刷新几次,后台结果如下:
由此可见,不使用@Bean注解,只有当页面刷新(即doRestEcho1方法执行),该方法(restTemplate())才会执行,且同doRestEcho1执行次数一样
这样对比,结果显而易见,@Bean注解的对象或方法确实被Spring管理了,且这样更高效,因为这里也可以很清楚地看见,他只创建了一个对象,却可以使用无数次,而没别管理的则是使用一次创建一次对象;通过查询,Spring管理对象默认情况下是单例模式(即只创建一次对象,却可以使用很多次),且是饿汉式。当然这只是有没有注解的区别表现之一。
二,@Bean与@Autowired对应使用
1.问题发现
众所周知,Spring通过@Bean将对象交给Spring管理,通过@Autowired实现自动装配,那么假如是返回类型一致的不同方法呢,显然是不可以的
2.问题分析
让我们看看是什么问题
什么意思?
不能自动装配。有多个’RestTemplate’类型的bean
其实也很好理解,你两个返回值一样,凭什么判定你自动装配的是那一个方法?
3.问题解决
方法一,同名
Spring中在这样的情况下回自动根据你自动装配对象的名称与方法名是否一致来判断,所以,这里只需让你自动装配的方法名与Spring管理的方法名称一致即可,如下:
方法二,@Qualifier指定
使用@Qualifier指定名称,如下:
方法三,在@Bean主键中添加属性
@Bean()中填入name属性
方法四,使用不同的注解
就比如一个Spring管理方法不止一个注解,且两者之间注解不同,那么在自动装配时只需写上对应的注解即可,如下:
当然,这些注解不是随便加的,而是根据需求加的,所以严谨来说,这也不能算是一个解决方案
总而言之,我们使用官方提供的,让你的自动装配对象名称与方法对象一致(即方法一),岂不是最方便?
三,不在启动类所在包下如何是文件运行
众所周知,Spring项目中,默认执行启动类所在包下的文件,那么不在该包下,如何执行呢?
方法一,使用@Bean注解
执行结果
方法二,@Import注解
将一个bean交给spring管理时,假如这个bean不在spring启动类所在包或子包中,所以可以通过import方法将类导入到配置类中
有人会说包扫描,但其实这里最好不要用包扫描,涉及到底层,大概就是@SpringBootApplication注解设定默认扫描其下的,本人小白QAQ。
@SpringBootApplication包扫描并没有指定,所以就默认当前启动类所在包下,既然人家都没指定包,我们也最好不要指定了。
四,@ConditionalOnMissingBean与@ConditionalOnBean
1.@ConditionalOnMissingBean
官方解释:Spring容器不存在指定class实例对象时,对应配置才生效
这个是指如果该对象已被Spring管理,则不再创建
运行结果:
可见setDefault2并没有被执行
如果没有对应bean,则创建
2.@ConditionalOnBean
官方解释:Spring容器存在指定class实例对象时,对应配置才生效
即只有这个对象已将存在才会被创建,就比如连接池,只有连接池有数据对象,才会创建,否则不会创建。