Spring条件装配

编程式条件装配(一般不实用)

1.Profile (应用于配置文件)

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {

	String[] value();
}

上个帖子中增加

// 小狗类的配置类
@Configuration
public class MyConfiguration {

    @Bean
    public Dog jinmao() {
        return new Dog("金毛");
    }

    @Bean
    public Dog demu() {
        return new Dog("德牧");
    }

    @Bean
    public Dog noname() {
        return new Dog();
    }
}

// 小狗类
public class Dog {

    public Dog() {
        System.out.println("我是狗的无参构造");
    }

    public Dog(String name) {
        System.out.println("我是狗的有参构造, 狗的名字是" + name);
    }

}

// 注解引入 小狗配置类
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({AnimalServiceImpl.class, MyConfiguration.class})
public @interface EnableMarket {

}

// 运行之前的test文件 最终结果 配置类中的信息都注册进来了
我是狗的有参构造, 狗的名字是金毛
我是狗的有参构造, 狗的名字是德牧
我是狗的无参构造
我是猫,我的名字是:小花

这次把配置类加上@Profile(“animal”)注解

@Configuration
@Profile("animal")
public class MyConfiguration {

    @Bean
    public Dog jinmao() {
        return new Dog("金毛");
    }

    @Bean
    public Dog demu() {
        return new Dog("德牧");
    }

    @Bean
    public Dog noname() {
        return new Dog();
    }
}
// 运行结果, 没有生效
我是猫,我的名字是:小花

接下来修改环境中的ActiveProfile属性

public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
                StartConfig.class);
        ctx.getEnvironment().setActiveProfiles("animal");
    }
 // 输出结果为空 小狗配置类还是没有生效

以上代码中 没有生效的原因是:new AnnotationConfigApplicationContext()中传入了参数,所以直接就将所有的Bean注册完成了。

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		// 注册相关Bean
		register(componentClasses);
		// refresh生效
		refresh();
	}
	// 无参构造
	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

修改启动代码:

// 改代码按照AnnotationConfigApplicationContext 类的有参构造重构
public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().setActiveProfiles("animal");
        // 之后再注册所有的Bean
        ctx.register(StartConfig.class);
        ctx.refresh();
    }
// 输出结果
我是狗的有参构造, 狗的名字是金毛
我是狗的有参构造, 狗的名字是德牧
我是狗的无参构造

声明式条件装配

如下图配置
在这里插入图片描述
运行测试方法

  public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
                StartConfig.class);
    }
	
// 输出结果
我是狗的有参构造, 狗的名字是金毛
我是狗的有参构造, 狗的名字是德牧
我是狗的无参构造

上图debug之后

public abstract class AbstractEnvironment implements ConfigurableEnvironment {
	@Override
	public void setActiveProfiles(String... profiles) {
		// debug此处 设置Profiles方法中读取到 profiles中有animal
		Assert.notNull(profiles, "Profile array must not be null");
		if (logger.isDebugEnabled()) {
			logger.debug("Activating profiles " + Arrays.asList(profiles));
		}
		synchronized (this.activeProfiles) {
			this.activeProfiles.clear();
			for (String profile : profiles) {
				validateProfile(profile);
				this.activeProfiles.add(profile);
			}
		}
	}
}

将参数animal改为cat,输出结果为空。

实际中Profile的用处

// 配置数据源 按照环境配置数据源(编程式, 还有配置文件式 使用的比较多)
@Configuration
public class DataSourceConfiguration {

    @Bean
    @Profile("dev")
    public DataSource devDataSource() {
        return null;
    }

    @Bean
    @Profile("test")
    public DataSource testDataSource() {
        return null;
    }

    @Bean
    @Profile("prod")
    public DataSource prodDataSource() {
        return null;
    }
}

@Conditional注解

@Conditional 是在 SpringFramework 4.0 版本正式推出的,它可以让 Bean 的装载基于一些指定的条件,换句话说,被标注 @Conditional 注解的 Bean 要注册到 IOC 容器时,必须全部满足 @Conditional 上指定的所有条件才可以。
常用的注解,也可以自己定义
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值