0
点赞
收藏
分享

微信扫一扫

【Spring】IoC容器 控制反转 与 DI依赖注入 配置类实现版本 第四期

肉肉七七 2024-02-26 阅读 9

文章目录


基于 配置类 方式管理 Bean

从 xml 到 完全注解 配置!
1

一、 配置类和扫描注解

1

//使用注解读取外部配置,替代 <context:property-placeholder标签
@PropertySource("classpath:jdbc.properties")
//使用@ComponentScan注解,可以配置扫描包,替代<context:component-scan标签
@ComponentScan("com.doug.ioc01")
//标注当前类是配置类,替代application.xml 
@Configuration
public class javaConfiguration {
    /*
    *  1. 添加@Configuration 标识为配置类
    *  2. 包扫描注解配置:
    *       2.1 @ComponentScan({"com.doug.ioc01","com.doug.ioc02"}) 多个包 中括号+逗号分割
    *       2.2 引用外部配置文件  
    *       2.3 声明第三方依赖的bean组件
    * */
}

测试:

    @Test
    public void testIoc_01(){
    	// AnnotationConfigApplicationContext 根据配置类创建 IOC 容器对象
        AnnotationConfigApplicationContext context = 
        			new AnnotationConfigApplicationContext(javaConfiguration.class);
        StuController bean = context.getBean(StuController.class);
        bean.show();
    }

也可以使用 no-arg 构造函数实例化 AnnotationConfigApplicationContext ,然后使用 register() 方法对其进行配置。

// AnnotationConfigApplicationContext-IOC容器对象
ApplicationContext iocContainerAnnotation = 
new AnnotationConfigApplicationContext();
//外部设置配置类
iocContainerAnnotation.register(MyConfiguration.class);
//刷新后方可生效!!
iocContainerAnnotation.refresh();

二、@Bean定义组件

`

属性只在当前方法使用,直接写成形参

//标注当前类是配置类,替代application.xml    
@Configuration
//引入jdbc.properties文件
@PropertySource({"classpath:application.properties","classpath:jdbc.properties"})
@ComponentScan(basePackages = {"com.doug.components"})
public class MyConfiguration {

    //如果第三方类进行IoC管理,无法直接使用@Component相关注解
    //解决方案: xml方式可以使用<bean标签
    //解决方案: 配置类方式,可以使用方法返回值+@Bean注解
    @Bean
    public DataSource createDataSource(@Value("${jdbc.user}") String username,
                                       @Value("${jdbc.password}")String password,
                                       @Value("${jdbc.url}")String url,
                                       @Value("${jdbc.driver}")String driverClassName){
        //使用Java代码实例化
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driverClassName);
        //返回结果即可
        return dataSource;
    }
}

三、高级特性:@Bean注解细节

    /*
     * @Bean会真正让配置类的方法创建的组件存储到IOC容器
     *
     * 1. beanName
     *       默认:方法名
     *       指定:name/value 属性起名字,覆盖方法名
     *
     * 2. 周期方法指定
     *       原有注解方法:PostConstruct + PreDestroy
     *       bean属性指定:initMethod / destroyMethod
     *
     * 3.作用域
     *       @Scope 默认单例
     *
     * 4.如何引用其他ioc组件
     *       直接调用对方的bean方法
     *       直接形参变量引入,要就必须有对应组件,如有多个,形参名 = 组件id标识 即可
     * */

    @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
    @Bean(name = "dataSource",initMethod = "",destroyMethod = "")
    public DataSource createDataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean(name = "dougSource")
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    /**
     * 方法一:
     *   直接把方法引入
     * @return
     */
    @Bean
    public JdbcTemplate jdbcTemplate(){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(createDataSource());
        return jdbcTemplate;
    }

    /**
     * 方法二:
     *   使用形参的方式,IOC容器会自动装配,可以一个或多个
     * @return
     */
    @Bean
    public JdbcTemplate jdbcTemplate2(DataSource dataSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //使用形参的方法,就必须要有这个类型的参数已经被注入了,
        // 就是上面的createDataSource方法被@Bean注解标识了(没有标注是会报错的)
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }

    /**
     * 如果是多个形参的情况,根据传入参数的名字对应bean设置的name,选择
     */
    @Bean
    public JdbcTemplate jdbcTemplate3(DataSource dataSource,DataSource dougSource){
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        //使用形参的方法,就必须要有这个类型的参数已经被注入了,
        // 就是上面的createDataSource方法被@Bean注解标识了(没有标注是会报错的)
        // 如果是多个形参的情况,根据传入参数的名字对应bean设置的name,选择
        jdbcTemplate.setDataSource(dougSource);
        return jdbcTemplate;
    }

四、高级特性:@Import扩展

@Import 注释允许从另一个配置类加载 @Bean 定义
也就是 :
当有A B两个配置类, A中引入@ImportB
在实例化配置类时 , 只要引入A就可以,B会跟着一起。

@Configuration
public class ConfigA {

  @Bean
  public A a() {
    return new A();
  }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {

  @Bean
  public B b() {
    return new B();
  }
}

容器实例化只需要引入 ConfigB.class (但是AB都可以用);

在实例化上下文时不需要同时指定 ConfigA.classConfigB.class ,只需显式提供 ConfigB

public static void main(String[] args) {
  ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);

  // now both beans A and B will be available...
  A a = ctx.getBean(A.class);
  B b = ctx.getBean(B.class);
}

此方法简化了容器实例化,因为只需要处理一个类,而不是要求在构造期间记住可能大量的 @Configuration 类。

五、基于注解+配置类方式整合三层架构组件

将原xml 配置第三方类 都使用 配置类来写,其余用都用注解,也就是完全注解开发,舍弃了在xml里面配置

配置类:

@PropertySource("classpath:jdbc.properties")
@ComponentScan("com.doug")
@Configuration
public class MyConfiguration {

    @Bean
    public DataSource dataSource(
            @Value("${doug.url}") String url, @Value("${doug.driver}") String driver,
            @Value("${doug.username}") String username, @Value("${doug.password}") String password
    ) {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        return jdbcTemplate;
    }
}

1


总结

1
注解+配置类 IoC方式总结

  1. 完全摒弃了XML配置文件
  2. 自定义类使用IoC和DI注解标记
  3. 第三方类使用配置类声明方法+@Bean方式处理
  4. 完全注解方式(配置类+注解)是现在主流配置方式
举报

相关推荐

0 条评论