Spring注解的学习(一)——组件注解

本来还想继续学习SpringBoot的,结果发现SpringBoot 的时候,很多注解都不懂,于是这几次先回头学习一下Spring 的注解相关内容。

一.一个大前提

  Spring认为所有的组件都应该放在IOC容器中,组件的关系通过容器进行装配(也就是依赖注入)

二. 简单的注入一个Bean 对象,使用配置文件和使用注解方法的区别

1.原来Bean的注入方式:1.现在xml文件进行写入,2.接着读取配置文件成为一个容器对象,并从中获取出对应的bean对象。(高级的就是使用包扫描)

Spring注解的学习(一)——组件注解

Spring注解的学习(一)——组件注解

 

 

2.注解方法:1.先写一个配置类(相当原来的配置文件bean.xml),类需要用@Configuration  2.在类中写方法,并用@Bean注解(相当原来配置文件中的Bean配置,其中原来配置文件中的类型class就是这个方法的返回对象;id默认就是方法的方法名,当然可以再@Bean(“方法名”)这里自定义Bean方法名)3.使用:同样先获取容器对象(不过这次是AnnotationConfigApplicatioContext),然后获取bean对象

 

 

Spring注解的学习(一)——组件注解

Spring注解的学习(一)——组件注解

三.注解Bean对象的相关(条件过滤等)

1.过滤器

原来当使用配置文件模式时,出现很多配置对象的时候,我们在配置文件中使用了包扫描,类中用@Service @[email protected]等进行注解

Spring注解的学习(一)——组件注解

 

     注解模式的话,是在主类(相当于原来配置文件)上用@ComponetScan(value=”要扫描的包名”)进行注解(相当扫描注解),当然除了配置value,还可以配置其他,例如要求扫描的时候,要包含哪些不包含哪些:

Spring注解的学习(一)——组件注解

(@Compnents 中)

且应该注意的是,由于@compnents默认打开了扫描包下所有,因此如果想让includeFilters生效,那么需要加入:useDefaultFilters = false

Spring注解的学习(一)——组件注解

 

FilterType.ANNOTATION:按注解类型

FilterType.ASSIGNABLE_TYPE按指定类型,包括其子类,实现类

FilterType.ASPECTJ:使用ASPECTJ表达式

FilterType.REGEX:使用正则指定

FilterType.CUSTOM:使用自定义规则

2.是否是单例 :

@Bean注解默认都是单实例的,当然可以类似配置文件中,用Scope来指定Bean 对象不是单实例,而是多实例。注解方式用的是@Scope .这里主要讲解一下两个值的不同情况。

Spring注解的学习(一)——组件注解

针对于默认的单实例,由于对象是在容器初始化的时候就创建,如果觉得太臃肿,其实也可以再第一次调用的时候再创建——懒加载。@lazy

3.同样的条件过滤

@Condition 注解,用于条件过滤,符合条件就可以注入到ioc容器中,不符合就不可以。

该注解的类如下:

Spring注解的学习(一)——组件注解

表明应该传入一个Condition实现类的数组类型,而Condition 接口如下

Spring注解的学习(一)——组件注解

综合来说,如果matches方法返回true,那么被注解的对象可以被注入到ioc容器中,反之不可以。于是我们创建了两个实现了Condition接口的类,一个定义返回false,一个定义返回true;(这里我们先不讨论方法的参数)

Spring注解的学习(一)——组件注解

Spring注解的学习(一)——组件注解

这样的结果就是,person01对象可以注入到容器ioc中,而person02对象无法注入进去。

对方matches方法,其实conditionContext字面理解就是上下文对象,你可以根据从这个对象获取的不同信息进行判断,返回true、false

三.Spring 注入Bean对象的几种方法

1.使用包扫描和组件标注(@Controller,@Service....)的方法,不过这个方法有个缺陷,就是只用在自己写的类上(因为@Contorller.....都是注解在类上)

2.使用@Bean 这个就可以用在非自己写的类上了,你只有将Bean注解在一个方法上,然后该方法创建一个第三方类就可以了

[email protected](快速给容器中导入一个组件)

[email protected](要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名,例如@Import(MyTest.class)

3.2.ImportSelector:返回需要导入的组件的全类名数组,看下面这个接口,应该就是让我们写一个实现该接口的类,然后方法selectImports返回的要导入类的全命名的数组

Spring注解的学习(一)——组件注解

例如我下面就导入了是三个类(方法参数我们先不管)

Spring注解的学习(一)——组件注解

然后在我们的配置类上加入注解@Import({ MySelector.class})就可以了

3.3.ImportBeanDefinitionRegistrar:手动注册bean到容器中。
其实这个类似于第二个,需要自己实现一个类,不同在于第二个是返回类给Spring  IOC容器加载,这个的话是直接自己手动加载(第一个参数可以用来做条件判断,第二个是实现了手动加载)

Spring注解的学习(一)——组件注解

Spring注解的学习(一)——组件注解

4.使用工厂模式导入到容器,使用Spring提供的 FactoryBean(工厂Bean),使用工厂的

GetObjectType或者getObject 返回的结果注入到容器中。例如我们自定义了一个类实现了ColorFactoryBean ,然后将这个类注入到容器中,这样的话ColorFactoryBean中返回的类对象也会注入到容器中

Spring注解的学习(一)——组件注解

需要注意的是:默认获取到的是工厂bean调用getObject创建的对象,如果要获取工厂Bean本身,我们需要给id前面加一个&

 &colorFactoryBean