本文是学习Spring的简单使用的文章,不涉及源码分析,非常适合新手学习(我的Spring系列的文章均基于Spring5.X,均使用注解式开发)
一.Ioc中bean的注册方法总结
1.@configuration+@bean注解
@configuration注解是Spring注解版的核心注解,后面源码分析文章会详细介绍
使用方式:
默认的beanDedfine中的beanName为方法名的返回值,但是可以在@bean中修改(参考Spring的doc文档)
关于beanName和bean alias之间的关系我会在后面源码分析的文章中详细介绍
测试一下,结果如下:
2.@componentScan+@component(包括@Repositery,@service,@controller)实现注入
查阅@componentScan的doc文档,发现@componentScan可以是用value来指定扫描的包,使用includeFilters和excludeFilters来指定排除和包含策略(注意:includeFilters必须要和useDefaultFilters=false连用)
例如上面的例子中扫描"com.iflytek"包中包含被@Service注解的类排除被@Controller注解的类(这种做法在后面springboot项目手动注入数据源的时候非常有用,手动注入数据源之前最好排除Springboot自动注入的数据源)
还可以使用自定义的规则来指定类是否会被注入
然后自己指定规则即可
@componnetScan注解在jdk8 中还是被源注解@repeatable修饰的注解,可以一直写,一直向ioc中注入bean
及其重要的@condition注解
Spring4之后,提供了@condition注解,在Springboot中大量使用用法和上面的TypeFilter很像,具体用法如下:
通过对该注解的封装可以很简单的实现SpringBoot中的@ConditionOn注解
3.@import注解向ioc中注入bean
其实这种方式在平时开发中用的很少,但是Spring底层用的比较多,典型的Springboot中的@EnableXXX注解底层均依赖该注解
用法:在full 配置类中使用@Import(XXX.class,MyImportSelector.class,MyImportBeanDefineRegistry.class)可以向容器中导入xxx类,以及myImportSelector类的selectImports方法返回的字符串数组所代表的类 myImportSelector需要实现importSelector接口
其中selectImports方法的参数AnnotationMetaData代表该类的所有注解信息,可以通过AnnotationMetaData来获取类的注解信息并根据注解信息来做判断是否导入容器中
MyImportBeanDefineRegistry的方法registryBeanDefine可以直接向beanDefineRegistry中注入bean(beanDefineRegistry的实现类就是具体的beanFactory,后面会详细分析此接口)
4.通过FactoryBean注册bean
这种方式较为简单,自己实现一个类实现FactoryBean接口,覆写getObject方法即可(还可以覆写isSingle方法指定是否单例),高版本的Spring支持范型写法,更加方便
注意:如果想要获取factoryBean本身可以使用beanFactory的getBean方法名字前加上#符号即可,Spring框架和其他框架整合时大量使用该类
二.Spring中bean的单例和多例的设置
使用@Scope注解即可完成,常用的是”singlton“和“protoType”,singleton是单例,默认容器启动时就创建对象并注册,protoType是多例,当使用beanFactory的getBean方法是才会创建对象并注入
注意:单例的bean既可以启动时加载也可以lazy加载(启动时不加载,获取bean的时候在加载),使用@Lazy注解即可
三.bean的生命周期的管理
Spring允许开发人员手动管理bean的生命周期,主要方式总结如下:
1.在@bean注解中指定initMethod(在创建bean实例之前被回调)和destoryMethod(在容器被销毁后回调)
2.initationBean接口:afterPropertySet()该方法在bean工厂完成对所有的bean的属性赋值完成之后调用
3.@postConstruct注解:被该注解注解的方法会在该bean被创建完成后,并且被注入容器之后调用(di完成之后)
4.beanPostProcessor接口(重点):Spring的重要接口,@autoWire注解和aop都是通过该接口来实现的,该接口有2个回调:
postProcessorBeforeInitialization:
该方法在populaionBean方法之后,在bean的任何初始化方法之前(例如initationBean的afterPropertySet和initMethod方法)
postProcessorAfterInitialization:
该方法在populationBean方法之后,在bean的任何初始化方法之后被回调
四.Spring中bean的获取
说完了往ioc容器中加入bean的方法,下面要关注的就是从ioc中获取bean的方法:
1.@autoWired注解
这个注解应该是使用最多的啦,因为被Spring管理起来的基本都是无状态的bean,但是这个注解用起来还是有坑的
1.容器中无bean的时候会报错
可以将该注解的required属性设置为false即可
2.容器中有多个bean如何取到自己想要的bean
1⃣️.可以结合@qualify(value="bean的名称或者别名")来获取 指定的bean
2⃣️.可以在bean上面加入@Primary注解,表示该按类型装配bean时,优先装配该bean
2.@Resource注解和@Inject注解
@resource(name=“”)注解默认按照bean的名称进行装配
@inject注解用法等同于@autowired,还要导入JSR 330jar包,不建议使用
3.使用beanUtils
如果小伙伴们嫌弃注解使用不方便,建议自己封装一个beanUtils(实现applicationContextAware接口即可)就可以得到ioc容器的引用,按类型取还是按照bean的名字取随心所欲,还可以按照别名取,获取环境变量,遍历所有的bean等等。