源码框架-Spring IOC-04-往IOC容器添加组件

一、@Conditional进行条件判断是否能加入IOC

场景:

  1. 二个组件BertService 和BertDao ,我的BertService组件是依赖于BertDao的组件
  2. 二个组件UserService 和UserDao ,我的UserService组件是依赖于UserDao的组件,但不将UserDao放入IOC

应用:自己创建BertCondition、UserCondition的类实现Condition接口

public class BertDao {
    public BertDao() {
        System.out.println("创建构造器");
    }
}

public class BertService {
    public BertService() {
        System.out.println("创建构造器BertService");
    }
}

public class BertCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //判断容器中是否有bertDao的组件
        if(context.getBeanFactory().containsBean("bertDao")) {
            return true;
        }
        return false;
    }
}

public class UserDao {
    public UserDao() {
        System.out.println("创建构造器UserDao");
    }
}

public class UserService {
    public UserService() {
        System.out.println("创建构造器UserService");
    }
}

public class UserCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //判断容器中是否有userDao的组件
        if(context.getBeanFactory().containsBean("userDao")) {
            return true;
        }
        return false;
    }
}

public class ConditionalConfig {
    @Bean
    public BertDao bertDao() {
        return new BertDao();
    }

    // 当容器中有bertDao的组件,那么bertService才会被实例化.
    @Bean
    @Conditional(value = BertCondition.class)
    public BertService bertService() {
        return new BertService();
    }

    // 当容器中有userDao的组件,那么userService才会被实例化
    @Bean
    @Conditional(value = UserCondition.class)
    public UserService userService() {
        return new UserService();
    }

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

运行结果:

创建构造器BertDao

创建构造器BertService

 

二、往IOC 容器中添加组件的方式

1、通过@CompentScan +@Controller @Service @Respository @compent

适用场景: 针对我们自己写的组件可以通过该方式来进行加载到容器中。

2、通过@Bean的方式来导入组件(适用于导入第三方组件的类)

3、通过@Import来导入组件 (导入组件的id为全类名路径)

3.1、

public class BertImportBean {

    public BertImportBean() {

        System.out.println("创建构造器BertImportBean");

    }

}

 

3.2、通过@Import 的ImportSeletor类实现组件的导入 (导入组件的id为全类名路径)

public class BertImportSelectBean {

    public BertImportSelectBean() {

        System.out.println("创建构造器BertImportSelectBean");

    }

}

public class BertImportSelector implements ImportSelector {

 

    // 可以获取导入类的注解信息

    @Override

    public String[] selectImports(AnnotationMetadata importingClassMetadata) {

        return new String[]{"com.bert.importbean.BertImportSelectBean"};

    }

}

 

3.3、通过@Import的 ImportBeanDefinitionRegister导入组件 (可以指定bean的名称)

public class BertImportDefinitionBean {

    public BertImportDefinitionBean() {

        System.out.println("创建构造器BertImportDefinitionBean");

    }

}

public class BertBeanDefinitionRegister  implements ImportBeanDefinitionRegistrar {

    @Override

    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        //创建一个bean定义对象

        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(BertImportDefinitionBean.class);

        //把bean定义对象导入到容器中

        registry.registerBeanDefinition("bertImportDefinitionBean", rootBeanDefinition);

    }

}

3.4、测试

@Configuration

@Import(value = {BertImportBean.class, BertImportSelector.class, BertBeanDefinitionRegister.class})

public class ImportBeanConfig {

    public static void main(String[] args) {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportBeanConfig.class);

    }

}

运行结果:

创建构造器BertImportBean

创建构造器BertImportSelectBean

创建构造器BertImportDefinitionBean

 

4、通过实现FacotryBean接口来实现注册 组件

public class BertFactory {
    public BertFactory() {
        System.out.println("创建构造器BertFactory");
    }
}

public class BertFactoryBean implements FactoryBean<BertFactory> {
    // 返回bean的对象
    @Override
    public BertFactory getObject() throws Exception {
        return new BertFactory();
    }

    // 返回bean的类型
    @Override
    public Class<?> getObjectType() 
        return BertFactory.class
    }

    // true: 单实例,每次获取都是同一个bean
    // false : 多实例,每次获取都会创建一个新的bean
    @Override
    public boolean isSingleton() {
        return false;
    }
}

@Configuration
public class BertFactoryConfig {
    @Bean
    public BertFactoryBean bertFactoryBean() {
        return new BertFactoryBean();
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new 
               AnnotationConfigApplicationContext(BertFactoryConfig.class);
        System.out.println(ctx.getBean("bertFactoryBean"));
        System.out.println(ctx.getBean("bertFactoryBean"));
    }
}

运行结果:

创建构造器BertFactory

com.bert.factory.BertFactory@530612ba

创建构造器BertFactory

com.bert.factory.BertFactory@2a40cd94

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值