本来还想继续学习SpringBoot的,结果发现SpringBoot 的时候,很多注解都不懂,于是这几次先回头学习一下Spring 的注解相关内容。
一.一个大前提
Spring认为所有的组件都应该放在IOC容器中,组件的关系通过容器进行装配(也就是依赖注入)
二. 简单的注入一个Bean 对象,使用配置文件和使用注解方法的区别
1.原来Bean的注入方式:1.先在xml文件进行写入,2.接着读取配置文件成为一个容器对象,并从中获取出对应的bean对象。(高级的就是使用包扫描)
2.注解方法:1.先写一个配置类(相当原来的配置文件bean.xml),类需要用@Configuration 2.在类中写方法,并用@Bean注解(相当原来配置文件中的Bean配置,其中原来配置文件中的类型class就是这个方法的返回对象;id默认就是方法的方法名,当然可以再@Bean(“方法名”)这里自定义Bean方法名)3.使用:同样先获取容器对象(不过这次是AnnotationConfigApplicatioContext),然后获取bean对象
三.注解Bean对象的相关(条件过滤等)
1.过滤器
原来当使用配置文件模式时,出现很多配置对象的时候,我们在配置文件中使用了包扫描,类中用@Service @Compnents@Dao等进行注解
注解模式的话,是在主类(相当于原来配置文件)上用@ComponetScan(value=”要扫描的包名”)进行注解(相当扫描注解),当然除了配置value,还可以配置其他,例如要求扫描的时候,要包含哪些不包含哪些:
(@Compnents 中)
且应该注意的是,由于@compnents默认打开了扫描包下所有,因此如果想让includeFilters生效,那么需要加入:useDefaultFilters = false
FilterType.ANNOTATION:按注解类型
FilterType.ASSIGNABLE_TYPE:按指定类型,包括其子类,实现类
FilterType.ASPECTJ:使用ASPECTJ表达式
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
2.是否是单例 :
@Bean注解默认都是单实例的,当然可以类似配置文件中,用Scope来指定Bean 对象不是单实例,而是多实例。注解方式用的是@Scope .这里主要讲解一下两个值的不同情况。
针对于默认的单实例,由于对象是在容器初始化的时候就创建,如果觉得太臃肿,其实也可以再第一次调用的时候再创建——懒加载。@lazy
3.同样的条件过滤
@Condition 注解,用于条件过滤,符合条件就可以注入到ioc容器中,不符合就不可以。
该注解的类如下:
表明应该传入一个Condition实现类的数组类型,而Condition 接口如下
综合来说,如果matches方法返回true,那么被注解的对象可以被注入到ioc容器中,反之不可以。于是我们创建了两个实现了Condition接口的类,一个定义返回false,一个定义返回true;(这里我们先不讨论方法的参数)
这样的结果就是,person01对象可以注入到容器ioc中,而person02对象无法注入进去。
对方matches方法,其实conditionContext字面理解就是上下文对象,你可以根据从这个对象获取的不同信息进行判断,返回true、false
三.Spring 注入Bean对象的几种方法
1.使用包扫描和组件标注(@Controller,@Service....)的方法,不过这个方法有个缺陷,就是只用在自己写的类上(因为@Contorller.....都是注解在类上)
2.使用@Bean 这个就可以用在非自己写的类上了,你只有将Bean注解在一个方法上,然后该方法创建一个第三方类就可以了
3.@Import(快速给容器中导入一个组件)
3.1.@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名,例如@Import(MyTest.class)
3.2.ImportSelector:返回需要导入的组件的全类名数组,看下面这个接口,应该就是让我们写一个实现该接口的类,然后方法selectImports返回的要导入类的全命名的数组
例如我下面就导入了是三个类(方法参数我们先不管)
然后在我们的配置类上加入注解@Import({ MySelector.class})就可以了
3.3.ImportBeanDefinitionRegistrar:手动注册bean到容器中。
其实这个类似于第二个,需要自己实现一个类,不同在于第二个是返回类给Spring IOC容器加载,这个的话是直接自己手动加载(第一个参数可以用来做条件判断,第二个是实现了手动加载)
4.使用工厂模式导入到容器,使用Spring提供的 FactoryBean(工厂Bean),使用工厂的
GetObjectType或者getObject 返回的结果注入到容器中。例如我们自定义了一个类实现了ColorFactoryBean ,然后将这个类注入到容器中,这样的话ColorFactoryBean中返回的类对象也会注入到容器中
需要注意的是:默认获取到的是工厂bean调用getObject创建的对象,如果要获取工厂Bean本身,我们需要给id前面加一个&
&colorFactoryBean