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