发布于2021-05-29 22:17 阅读(704) 评论(0) 点赞(11) 收藏(3)
这里我做的这份笔记的意义仅仅是记录下自己初涉Spring的历程,既不是对官方API的深入解释,也不一定是对新手友好的、知识点详尽的一份学习清单。
综上,不喜勿喷,但是有问题欢迎评论区交流!
注解在配置Spring上比XML更好吗? 两种方式并无绝对的更好。不过目前的趋势是使用注解,尤其是对于不是特别大的项目。
@Autowire 用于自动装配,按照 类型 装配。
其中,不建议使用 @Autowire 注入,这强依赖于 Spring 上下文的,无法在脱离ioc容器创建对象,比如在进行单元测试的时候。
使用构造器注入,表达强依赖关系。
使用方法(不一定是setter),表达依赖的可选择关系。
由于@Autowire是按类型自动装配的,如果有过个bean的话Spring不知道找那个,
可以使用 @Primary 指定 bean 的优先级。
@Primary
@Component
public class ...{
}
以及
@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
配合 @Autowire 使用,可以根据 bean 的名字进行精确匹配。
此注解可以使用在 方法、字段、类型、参数,相当于在需要根据name进行标识的时候,就使用它。
注:
可能有人想用 @Resource 去彻底代替 @Autowire + @Qualifier。
在一定场景下是可以的。
但是 @Resource 只能用于字段,和单个参数的setter,对于注解构造函数和多个参数的方法,它无能为力。不过, @Autowire + @Qualifier 没有这个限制。
官方文档这里还讲了 自定义的 @Qualifier ,这里就不细讲了。
@Resource
有两个属性name
、type
匹配规则:
暂略。
@Value 通常用于注入外部属性。
这里还用到了 Spring表达式,不过这里仅仅使用读取即可。
@Component
public class MovieRecommender {
private final String catalog;
public MovieRecommender(@Value("${catalog.name}") String catalog) {
this.catalog = catalog;
}
}
在 application.properties
catalog.name=MovieCatalog
还可以使用SpEL进行读取值后动态计算生成值。
要自动检测这些类并注册相应的bean,就可以使用 @ComponentScan。
它的作用,找到这些bean,并把它注册到 ioc 容器里, 就像我们手动在 xml 配置一样。
对于SpringBoot应用这个注解可能不会直接被我们使用,
原因是 @SpringBootApplication已经使用了 这个注解,而这个注解会扫描 com.xxx.xxx包及其子包下所有的@Component 及其派生注解,所以一般情况下我们用不着。
但是如果有类写在启动类所在包的外面,而你又想使用它,就得用上这个注解了。
使用方法:
指定扫描的包(子包会自动扫描),指定过滤器。
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
@Bean注释的作用与元素相同。
@Bean可以结合其他注解使用
这些注解基本上是补全了XML的功能
//@Component
@Configuration
public class BeanHolder {
@Bean
public ExampleBean exampleBean() {
return new ExampleBean();
}
// 在类内调用,同样也会经过代理
// ( 很好理解,cglib生成的子类override上面的getExampleBean方法后,调用f()时,
// 根据类的多态,此时调用的getExampleBean方法是被增强过的方法
public void f() {
System.out.println(exampleBean());
System.out.println(exampleBean());
System.out.println(exampleBean());
}
}
它和如下的xml配置等效
<beans>
<bean id="exampleBean" class="com.xxx.BeanHolder"/>
</beans>
如果把这里的**@Configuration**换成 @Component会怎样?
注意,@Configuration类下被 @Bean 注解的方法,调用的时候会得到CGLIB代理的增强,
而@Component下的@Bean方法不经过代理,是标准的java调用。
如果@Bean修饰的方法被 static呢?
注意CGLIB生成的子类只会override非静态方法,所以static的@Bean方法不会被容器拦截。
技术上来说,CGLIB会动态生成BeanHolder的子类,然后override那个@Bean代理的方法。
注意,看到下面的图,你通过Spring容器拿到的类,其实已经不是你自己写的类了,而是经过cglib加强过的类。
Spring自己生成的bean的名字是有规则的,就是类名答第一个字母变成小写,而你可以自定义名称生成规则(不过似乎很鸡肋,没什么用)。
这个注解可以用在Bean class 和@Bean 方法上,用来指定作用域。
@Scope("prototype")
@Component
public class ...{
}
@Bean
@Scope("prototype")
public MyBean myBean(){
}
作者:程序员之神
链接:http://www.javaheidong.com/blog/article/207744/70058efcfd328f392087/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!