Spring-SpringIoC-配置类
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标签,扫描包中组件
@ComponentScan("com.xiaobai.ioc_01")
当扫描多个包时,用大括号包含,逗号隔开
@ComponentScan({"com.xiaobai.ioc_01","com.xiaobai.ioc_02"})
@PropertySource
在配置类上加此注解,代替context:property-placeholder标签,导入外部文件
@PropertySource("classpath:jdbc.properties")
使用配置类创建IoC容器
使用ApplicationContext子接口的实现类AnnotationCofigApplicationContext读取Java配置类创建IoC容器对象
ApplicationContext context = new AnnotationConfigApplicationContext(JavaConfiguration.class);
手动引入后刷新
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(JavaConfiguration.class);
context.refresh();
区别于ClassPathXmlApplicationContext实现类的setConfigLocations方法,在这里使用的时register方法引入外部文件
@Bean
第三方类的引用在配置类中是通过方法实现的
- 方法的返回值类型 = bean组件的类型或者其接口父类
- 方法的名字 = bean Id
- 方法体自定义实现过程,最后将组件对象返回即可
使用@Bean注解标识该方法,即使用配置类的方法创建组件对象储存到IoC容器中
@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注解可做用到形参列表中,如果参数只在该方法内使用一次,则可直接使用此注解映射参数到形参列表,不需要创建类中属性
@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
@Bean("dataSource")
@Bean(value = "dataSource")
@Bean(name = "dataSource")
周期方法
在配置类接管后,我们仍可以用 @PostConstrct + @ProDestroy来指定初始化和销毁方法
也可以使用@Bean注解中的initMethod和destoryMethod属性来指定初始化和销毁方法
@Bean(initMethod = "",destroyMethod = "")
作用域
与普通组件的作用域设置方法相同,同样是使用Scope注解(Scope可以作用于类或方法)
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON) //单例 默认值
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) //多例
自动装配
在使用三方类JdbcTemplate时,需要把Druid连接池DataSource注入到JdbcTemplate中
使用配置类,需要设置形参为所需组件对象,在加上@Bean注释后,IoC容器会自动查找容器内部的组件对象,完成注入
这个自动注入的过程与Autowired是相同的
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(dataSource);
return jdbcTemplate;
}
配置类
这个配置类中就包含了Druid连接池和JdbcTemplate的第三方注入
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;
/**
* 此类为Spring配置类,用以替换xml文件实现完全注解开发
*/
@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注解可以解决此问题
@Import(JavaConfigurationB.class) //将配置类B导入
在实际开发中,会存在很多很多个配置类,如果在使用时一一导入的话会非常麻烦
我们可以准备一个根配置类,在这个配置类中只做整合使用,最后使用时只使用这一个配置类创建容器即可
这个整合思路有点像vue中的App.vue