1、配置
采用注解方式配置IOC容器,有三种方式
- 纯注解形式,提供至少一个配置类(@Configuration标注的类)
- 纯注解形式,提供至少一个Bean(@Component等标注的类)
- 混合方式,提供配置类,使用@ImportResource引入Spring的配置文件。
2、创建
创建IOC容器上,本质上还是创建ApplicationContext对象,注解方式只是创建AnnotationConfigApplicationContext。根据上面三种配置方式创建IOC容器。
- 单个配置类:创建AnnotationConfigApplicationContext对象,参数为XXApp.class
public ApplicationContext singleConfig() { // 创建IOC容器本质是创建ApplicationContext对象 ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); return ac; }
2.多个配置类:有三种方式,第一种使用@Import注解,第二种方式多个XXApp.class参数,第三种方式调用register方法。
// 方式一 @Configuration @Import({AppConfig1.class,AppConfig2.class}) public class AppConfig {} // 方式二 ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class,AppConfig2.class); // 方式三,此时必须是AnnotationConfigApplicationContext对象, // ApplicationContext接口中无这些方法 ac.register(AppConfig1.class); ac.register(AppConfig.class);
3.纯注解形式,多个Component与Configuration注解相同,只不过IOC容器中只存在初始化时传入的几个Bean。
4.混合方式,使用@ImportResource注解
@Configuration @ImportResource({"classpath:spring/application.xml"}) public class AppConfig {}
无论是以上哪种方式,一个IOC容器对应一个AnnotationConfigApplicationContext对象。AppConfig可以获取其他Config注入的bean。
3、扫描bean
扫描Bean的知识点大致分为三类。
- 第一类是指定扫描路径,
- 第二类是添加过滤器和过滤条件。
- 第三类是使用Index,提升性能。
3.1 扫描路径
指定扫描路径的方式有两种
第一种使用@ComponentScan注解,通过设置basePackages指定bean所在包的名称,多个包名时使用逗号分隔,包名可以是正则表达,SpringEL表达式。
第二种调用context.scan方法,参数为包名。
3.2 添加过滤条件
添加过滤条件有两个含义,第一类是指给配置类上添加过滤条件,第二类是指给具体的某个bean上添加过滤条件。
第一类是给@Component-scan设置include-filter和exclude-filter属性,它们的值可以是以下五类:
- Annotation:根据类上的注解进行过滤,默认值
- Assignable:根据类或者类名进行过滤
- Aspectj:根据AspectJ的类型表达式对类名进行过滤
- Regex:根据正则表达式对类型进行过滤
- Custom:根据TypeFilter的实现类进行过滤。
第二类是给具体的bean上添加过滤条件,当满足条件时注入bean,不满足时跳过。
它是给具体的bean上添加@Conditional注解,并设置value属性,每一个value属性的值都是Condition接口的实现类。Condition接口只有一个方法matches,当满足条件时,该方法返回true,不满足条件时,返回false。
要添加自定义过滤条件,至少需要两个步骤
- 第一步,编写XXConditionImpl,实现Condition接口,
- 第二步,在类上添加@Conditional注解,并设置value的值为XXConditionImpl.class
现在springBoot中大量存在该注解,@Conditional和Condition都有自己的类结构。例如@ConditionalOnClass表示某个类是否在IOC容器中,当存在时满足条件,不存在时不满足条件。
想要深入了解,可以查看DataSourceAutoConfig的源码去理解该注解。
3.3 profile
Profile本质也是一种过滤条件,过滤条件是基于”环境”的,例如生产环境,测试环境。
使用@Profile注解的步骤有以下几步:
- 第一步:在bean上添加@profile注解,当激活的环境与设置的环境相等时,注入bean。方式有以下三种
- 在类上添加,在方法上添加,类上标注有@Component等,方法上有@Bean。
- 创建@Profile的元注解,在类上,方法上添加元注解。例如创建@Production注解
- 在配置文件中,给beans标签设置profile属性,相当于全局;或给单个bean标签设置profile属性。
2.第二步:激活profile。方式有四种
- 设置spring.profiles.active属性。Java argument形式,配置文件形式等等
- 调用context.getEnvironment().setActiveProfiles方法,参数为激活的环境。
- 指定默认的profile。
- 如果存在spring-test依赖,在配置类上添加@ActiveProfiles
设置默认profile的方式也有三种。
- 在配置类上添加@Profile注解
- 调用context.getEnvironment().setDefaultProfiles方法
- 设置spring.profiles.default属性。
Profile的值可以是单个环境,多个环境,或者是环境的逻辑表达式。
- 单个环境,@Profile(“envName”);
- 多个环境,@Profile({“envName1”,”envName2”}),它们是逻辑或关系,只要其中一个环境激活即加载。
- 逻辑表达式,与(&),或(|),非(!)。例如@Profile(“!envName”)。
3.4 添加索引
添加索引是指在注入bean时,给bean添加索引,在获取bean时会变快,提高性能。
添加索引的步骤有两步:
- 添加spring-context-indexer依赖。
- 在IOC容器中注入CandidateComponentsIndexer类。
如果想禁用此功能,又不想移除依赖,可以设置spring.index.ignore属性值为true。
4、集成web
当使用XML方式去集成Web时,需在web.xml中配置DispatcherServlet,并且指定配置文件路径即可。
注解方式本质也是一样的,只不过参数的值变为了配置类的包名。具体的设置如下。
<!-- webApplicationContext的类型 --> <context-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </context-param> <!-- 配置类的类全名--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>com.config.AppConfig</param-value> </context-param>
5、Properties
Properties的知识点大致分为三部分。第一部分介绍IOC如何查找变量,第二部分介绍如何修改查找变量的顺序,第三部分介绍如何引入自定义变量或Properties文件。
IOC查找变量的顺序跟spring boot基本是类似的。
- 首先是运行参数,如果是java application,运行参数指java argument。如果是web项目,运行参数是指context-param或者是context-config。
- 其次是系统变量,JVM系统变量,操作系统变量。
- 之后是配置文件,例如spring.properties,spring boot中的application.properties或application.yml
- 最后是自定义变量或者是引入的自定义Properties文件。
这些是由谁决定的呢?在介绍ApplicationContext对象时,它继承Environment接口,Environment接口又继承了PropertyResovler,变量查找的顺序是由Environment接口实现类决定的,默认的实现类名称是StandardEnvironment。如果需要理解和修改变量的查找顺序,可以查看相关类的源码。
要添加自定义变量,最好的方式是定义Properties文件,并通过@PropertySource注解引入。其中value属性为Properties配置文件的路径。