Spring5 注解编程基础组件(Annotation API)

1.配置组件(Configure Components)

(1)@Configuration:把一个类作为一个IoC容器,他的某个方法头上如果注解了@Bean,那么就会作为bean存在spring容器中

以前我们写在配置文件,配置一个个bean,现在使用这个注解即可

Spring5 注解编程基础组件(Annotation API)_第1张图片

Spring5 注解编程基础组件(Annotation API)_第2张图片

图一创建的类使用了注解@Configuration,然后里面@Bean注解了一个方法 

@Bean注解方法的返回值就作为实例存在ioc容器中了

图二中我们获取app然后获取实例即可

关于图一使用new 对象其实不是真的new出来的,是使用原型模式生成的,所以new几次都是同一实例

如下图

Spring5 注解编程基础组件(Annotation API)_第3张图片

  @Bean("person111")这里其实就是不使用方法名为实例名,而重新定义了一个

Spring5 注解编程基础组件(Annotation API)_第4张图片

我们再次用方法名获取实例就会报错

Spring5 注解编程基础组件(Annotation API)_第5张图片

改为person111又正常获取

Spring5 注解编程基础组件(Annotation API)_第6张图片

总结下:优先取bean注解的value,其次是取方法名

(2)@ComponentScan

就跟之前xml 中的 效果一样 ,注解在某类上时会扫描该类所在包下的所有类

如果你定义了包路径的话就扫描该路径下的所有组件,记住是组件,不是所有类,比如@Controller,@Service这种,或者@Component这种

Spring5 注解编程基础组件(Annotation API)_第7张图片

Spring5 注解编程基础组件(Annotation API)_第8张图片

可以看到person类有被扫描到

图一中@ComponentScan("com.robert.annotations.project")表示扫描该路径下所有组件加载到ioc容器中,正常来说该路径下的Person类不在此范围里,这里我们手动加了@Component注解,使其被扫描

但是,开发中,我们可能某些包的某些类不想扫描,这里我们就可以用过滤器excludeFilters 和 includeFilters 

这里就不演示 

@ComponentScan(value = "io.mieux",
        excludeFilters = {@Filter(type = FilterType.ANNOTATION,
        value = {Controller.class})})

意思就是我扫描io.mieux下的所有没有被@Controller注解的类

Spring5 注解编程基础组件(Annotation API)_第9张图片

这里除了使用注解过滤,当你规则比较复杂的时候,还可以使用正则表达式啊,过滤类啊等待,

好了,第二个注解@ComponentScan我就说到这,总的来说就是扫描一些类,将这些类的实例放到IoC容器中,

然后我要用的时候不需要new,使用依赖注入即可

(3)@Scope 

该注解用于指定作用域的,用在类上,这个注解也不复杂哦

Spring5 注解编程基础组件(Annotation API)_第10张图片

现在我们把@Scope("prototype")注解注释

Spring5 注解编程基础组件(Annotation API)_第11张图片

 

然后从容器中获取实例,可以看到是获取的相同的

现在解开注释

Spring5 注解编程基础组件(Annotation API)_第12张图片

 发现是不同的实例了

Spring5 注解编程基础组件(Annotation API)_第13张图片

这里关于这个注解不多说

Spring5 注解编程基础组件(Annotation API)_第14张图片

有四种场景:

不写时默认为单例

然后@Scope("prototype")代表每次获取实例创建新的

@Scope("request")表示在同一请求中,只创建一个实例

@Scope("session") 类似,表示在同一session中单例

第三个注解就到这

(4)@Lazy

延时加载本来是在容器启动时就创建实例,使用该注解后,在调用该对象方法或者说用到该对象时才创建实例,延时加载是单例模式

Spring5 注解编程基础组件(Annotation API)_第15张图片

Spring5 注解编程基础组件(Annotation API)_第16张图片

上两图,先分别在实例创建与测试时容器创建的时候加上打印语句

Spring5 注解编程基础组件(Annotation API)_第17张图片

可以看到是先将实例放入IoC,然后再打印初始化IOC容器

 

现在加上@Lazy注解

Spring5 注解编程基础组件(Annotation API)_第18张图片

再看控制台,可以看到使用时才创建对象并加入IOC容器,怎么说呢,懒加载就像之前说的懒汉模式,用的时候我才创建,这样当你项目庞大时能提升不少性能

Spring5 注解编程基础组件(Annotation API)_第19张图片

(5)@Conditional

意思是按照一定的条件判断是否给容器注册bean

Spring5 注解编程基础组件(Annotation API)_第20张图片

使用@Conditional注解要配合Condition类,我们这里先定义俩Condition

Spring5 注解编程基础组件(Annotation API)_第21张图片

Spring5 注解编程基础组件(Annotation API)_第22张图片

然后测试,此demo实现操作系统为windows时创建james,为linux时创建tom

Spring5 注解编程基础组件(Annotation API)_第23张图片

修改vm参数,模拟linux操作系统 

Spring5 注解编程基础组件(Annotation API)_第24张图片

此时测试创建tom实例

Spring5 注解编程基础组件(Annotation API)_第25张图片

(6)@Import

这个作用就是导入外部资源,相当于手动指定第三方资源,把其实例加载到IoC中

配置类,还是配置了一个bean person

Spring5 注解编程基础组件(Annotation API)_第26张图片

测试类,打印输出扫描到的类 

Spring5 注解编程基础组件(Annotation API)_第27张图片

新建Cat类Spring5 注解编程基础组件(Annotation API)_第28张图片

测试类中使用@Import(value = {Cat.class})

Spring5 注解编程基础组件(Annotation API)_第29张图片

发现打印的Ioc中的bean多了Cat类

Spring5 注解编程基础组件(Annotation API)_第30张图片

 

还有一种方式,可以自定义ImportSelector

比如说我只想导入某几个类,或者我只想导入类名包含 "AP"的类

新建dog跟mouse类

Spring5 注解编程基础组件(Annotation API)_第31张图片

自定义importSelector,import注解里的数组里加上

Spring5 注解编程基础组件(Annotation API)_第32张图片

测试,可以看到,IoC中多了mouse跟dog类实例

Spring5 注解编程基础组件(Annotation API)_第33张图片

继续,使用import注解还有第三种方式,这种更加体现了注解编程的灵活度

自定义MyImportBeanDefinitionRegistrator,里面逻辑是我如果Ioc注册列表里有Mouse跟Dog我就注册一个新的实例catt

Spring5 注解编程基础组件(Annotation API)_第34张图片

测试发现成功注册catt

Spring5 注解编程基础组件(Annotation API)_第35张图片

总结下,关于注册bean到IoC容器,有三种方式

1.@Bean 加一个注解一个

2.@ComponentScan可以注册某个包下的一堆组件

3.@Import  有三种方式(1.Xx.class,2.XximportSelector,3.XxImportBeanDefinitionRegistrator)

其实还有第四种

关于面试问的BeanFactory与FactoryBean区别:

其实FactoryBean就是spring内部的一个Bean,不过他的职责是负责将bean注册到IoC容器中,

而我们获取bean时使用FactoryBean即可获取

先整个MyFactoryBean,可以看到实现了三个方法,分别为返回对象,返回对象类型,是否单例

Spring5 注解编程基础组件(Annotation API)_第36张图片

在配置类中多加一个Bean

Spring5 注解编程基础组件(Annotation API)_第37张图片

可以看到返回的是MyFactoryBean对象,可以看到其实获取到的是monkey实例

Spring5 注解编程基础组件(Annotation API)_第38张图片

也就是说,FactoryBean的作用就是注册实例,而我们设置的单例为true,也可以看到测试结果中俩对象相同

好了@Import注解到此结束

(7)bean的生命周期

配置阶段只剩最后一类注解了就是关于bean的生命周期

新建Car类

Spring5 注解编程基础组件(Annotation API)_第39张图片

 

配置类

Spring5 注解编程基础组件(Annotation API)_第40张图片

initMethod = "start",destroyMethod = "stop",表示初始化与销毁对象时分别调用对应的方法

测试下

Spring5 注解编程基础组件(Annotation API)_第41张图片

然后是第二种

第二种是直接实现俩接口

Spring5 注解编程基础组件(Annotation API)_第42张图片

重写destroy与afterPropertiesSet方法

配置文件改回去

Spring5 注解编程基础组件(Annotation API)_第43张图片

Car类要加@Component注解 

Spring5 注解编程基础组件(Annotation API)_第44张图片

配置类加扫描组件的注解

Spring5 注解编程基础组件(Annotation API)_第45张图片

再次运行测试方法

Spring5 注解编程基础组件(Annotation API)_第46张图片

结果相同

现在说第三种

如图,使用注解@PostConstruct 与@PreDestroy

Spring5 注解编程基础组件(Annotation API)_第47张图片

 

第四种方式

自定义MyBeanPostProcessor继承BeanPostProcessor接口Spring5 注解编程基础组件(Annotation API)_第48张图片

这种方式最灵活,这样写定义类,可以在其中获取所有bean,可以针对性的处理

测试正常

Spring5 注解编程基础组件(Annotation API)_第49张图片

2.赋值组件(Injection Components)

这一部分的注解是日常开发中用的最多的,我先全部列举,你应该会有几个熟悉的

@Component,@Service,@Controller,@Repository,@Value,@Autowired,@PropertySource,@Qualifier,@Primary,@Resource,下面我一个个来讲解

@Component 泛指组件,当你的组件不好归类时,就用它进行标注

@Service,@Controller,@Repository都是@Component的子类,这四个注解都只是一个标注的作用,不过标注的对象不同

分别标注业务层,控制层,数据访问层

 

然后是@Value,这个注解就是起个赋值的作用

定义了一个类Bird,分别三种使用@Value的方式给属性赋值,分别是直接赋值,EL表达式,获取配置文件属性

Spring5 注解编程基础组件(Annotation API)_第50张图片

 

Spring5 注解编程基础组件(Annotation API)_第51张图片

使用配置文件属性时,记得在配置类上加上@PropertySource(value = "classpath:config.properties")

Spring5 注解编程基础组件(Annotation API)_第52张图片

然后测试时可以看到获取对象的属性被成功赋值

Spring5 注解编程基础组件(Annotation API)_第53张图片刚刚这块就包含俩注解,@Value与@PropertySource

 

下面说下autowired,这个注解就是注入

Spring5 注解编程基础组件(Annotation API)_第54张图片

Spring5 注解编程基础组件(Annotation API)_第55张图片

Spring5 注解编程基础组件(Annotation API)_第56张图片

使用autowired注解注入,

测试类中扫描这三个类的组件,其中编写service类时打印了dao的实例

Spring5 注解编程基础组件(Annotation API)_第57张图片

说明我们注入DemoService类中的DemoDao的实例就是IoC中的

 

接下来是@Qualifier注解,当你不想要注入Ioc中的bean时,使用这个注解可以注入你指定的bean

Spring5 注解编程基础组件(Annotation API)_第58张图片这里我在DemoDao中整了个flag,值为1,正常注入DemoDao的话flag为1

 

我现在自定义bean,里面的flag为2

Spring5 注解编程基础组件(Annotation API)_第59张图片

 

那么这个时候可以用Qualifier

Spring5 注解编程基础组件(Annotation API)_第60张图片

 

测试可以看到我们注入的就是flag为2的自定义bean

Spring5 注解编程基础组件(Annotation API)_第61张图片

 

把自定义里的flag改为4

Spring5 注解编程基础组件(Annotation API)_第62张图片

 

 

Spring5 注解编程基础组件(Annotation API)_第63张图片

 

使用@Resource注解

Spring5 注解编程基础组件(Annotation API)_第64张图片

@Resource是针对所有的资源,比@Autowired与@Qualifier优先级更高

 

最后一个注解@Primary 优先 当俩bean名称相同时,其中一个加上@Primary注解,将获得优先权

Spring5 注解编程基础组件(Annotation API)_第65张图片

3.织入组件(Weave Components)

@AppllicationContextAware:这是spring中的上下文环境对象,可以通过他得到IoC中的所有bean

还有一个是BeanDefinitionRegistryPostProcessor, 这个是用来注册额外的BeanDefinition的

 BeanDefinition就是Bean配置的封装而已

4.切面组件(Aspect Components)

@Transactional 配置事务信息

@EnableTransactionManagement 添加事务管理,就是开启事务

 

 

你可能感兴趣的:(冲高级之所学知识梳理,Spring)