Spring-SpringIoC-配置类
我们使用注解方式解放了很大一部分xml的功能,但仍然存在三个功能必须要在xml文件配置
- 使用<context:component-scan base-package=””/>标签配置扫描包
- 使用<context:property-placeholder location=””/>引入外部的配置文件
- location属性中的classpath表示相对路径,在项目中查找资源文件,再查找jar包
- 第三方类的IoC配置
XML格式的解析效率很低,为了解决这个问题,实现完全注解的配置,Spring提供了配置类
配置类是使用 方法+注解 来替代xml标签,最后实现完全注解开发,配置类的作用是替代xml
@Configuration
configuration中文释义:配置
创建config包下建立一个java文件,作为配置类
在类上加Configuration注解,声明此类为配置类
@ComponentScan
在配置类上加此注解,代替context:component-scan标签,扫描包中组件
1
| @ComponentScan("com.xiaobai.ioc_01")
|
当扫描多个包时,用大括号包含,逗号隔开
1
| @ComponentScan({"com.xiaobai.ioc_01","com.xiaobai.ioc_02"})
|
@PropertySource
在配置类上加此注解,代替context:property-placeholder标签,导入外部文件
1
| @PropertySource("classpath:jdbc.properties")
|
使用配置类创建IoC容器
使用ApplicationContext子接口的实现类AnnotationCofigApplicationContext读取Java配置类创建IoC容器对象
1
| ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfiguration.class);
|
手动引入后刷新
1 2 3
| AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(JavaConfiguration.class); context.refresh();
|
区别于ClassPathXmlApplicationContext实现类的setConfigLocations方法,在这里使用的时register方法引入外部文件
@Bean
第三方类的引用在配置类中是通过方法实现的
- 方法的返回值类型 = bean组件的类型或者其接口父类
- 方法的名字 = bean Id
- 方法体自定义实现过程,最后将组件对象返回即可
使用@Bean注解标识该方法,即使用配置类的方法创建组件对象储存到IoC容器中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @ComponentScan("com.xiaobai.ioc_01") @PropertySource("classpath:jdbc.properties") @Configuration public class JavaConfiguration { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password;
@Bean public DataSource dataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
|
拿Druid连接池距离,我们首先使用@PropertySource导入配置文件,使用@value映射配置文件内容到类中属性
创建返回值类型为DataSource的方法,将类中属性作为Jdbc四大件参数填写在对象中
使用@Bean标签标识后,该方法的返回对象就会被存放到IoC容器中,Bean Id为方法名
形参列表
@Value注解可做用到形参列表中,如果参数只在该方法内使用一次,则可直接使用此注解映射参数到形参列表,不需要创建类中属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @ComponentScan("com.xiaobai.ioc_01") @PropertySource("classpath:jdbc.properties") @Configuration public class JavaConfiguration { @Bean public DataSource dataSource( @Value("${jdbc.driver}") String driver, @Value("${jdbc.url}") String url, @Value("${jdbc.username}") String username, @Value("${jdbc.password}") String password ) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } }
|
BeanId
@Bean注解的默认BeanId是方法名,我们也可以在注解中手工配置Bean Id
1 2 3
| @Bean("dataSource") @Bean(value = "dataSource") @Bean(name = "dataSource")
|
周期方法
在配置类接管后,我们仍可以用 @PostConstrct + @ProDestroy来指定初始化和销毁方法
也可以使用@Bean注解中的initMethod和destoryMethod属性来指定初始化和销毁方法
1
| @Bean(initMethod = "",destroyMethod = "")
|
作用域
与普通组件的作用域设置方法相同,同样是使用Scope注解(Scope可以作用于类或方法)
1 2
| @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
自动装配
在使用三方类JdbcTemplate时,需要把Druid连接池DataSource注入到JdbcTemplate中
使用配置类,需要设置形参为所需组件对象,在加上@Bean注释后,IoC容器会自动查找容器内部的组件对象,完成注入
这个自动注入的过程与Autowired是相同的
1 2 3 4 5 6
| @Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; }
|
配置类
这个配置类中就包含了Druid连接池和JdbcTemplate的第三方注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.*; import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;
@ComponentScan("com.xiaobai.ioc_01") @PropertySource("classpath:jdbc.properties") @Configuration public class JavaConfiguration { @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) @Bean public DataSource dataSource( @Value("${jdbc.driver}") String driver, @Value("${jdbc.url}") String url, @Value("${jdbc.username}") String username, @Value("${jdbc.password}") String password ) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(driver); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; }
@Bean public JdbcTemplate jdbcTemplate(DataSource dataSource) { JdbcTemplate jdbcTemplate = new JdbcTemplate(); jdbcTemplate.setDataSource(dataSource); return jdbcTemplate; } }
|
@Import
当有多个配置类存在时,我们在加载配置类时,需要分别再加每一个配置类
使用@Import注解可以解决此问题
1
| @Import(JavaConfigurationB.class)
|
在实际开发中,会存在很多很多个配置类,如果在使用时一一导入的话会非常麻烦
我们可以准备一个根配置类,在这个配置类中只做整合使用,最后使用时只使用这一个配置类创建容器即可
这个整合思路有点像vue中的App.vue