• spring 高级装配



    一、环境与profile

    1、java配置profile

    public interface DateSourceInterFace {//下面两个实现的接口
        public void printInfo();
    }
    
    • 1
    • 2
    • 3
    @Component
    @Profile("dev")
    public class DevDateSour implements DateSourceInterFace{
        @Override
        public void printInfo() {
            System.out.println("this DEV profile.......");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @Component
    @Profile("pro")
    public class ProDateSour implements DateSourceInterFace{
        @Override
        public void printInfo() {
            System.out.println("this Pro profile.......");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    @ComponentScan//spring扫描到spring容器中创建bean对象
    @Configuration
    public class ProfileConfig {
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = ProfileConfig.class)
    @ActiveProfiles("pro")//当前激活pro环境
    public class ProfileTest {
        @Autowired
        private DateSourceInterFace dateSource;
        
        @Test
        public void test01(){
          dateSource.printInfo();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果:

    this Pro profile.......
    
    • 1

    2、xml中配置profile

    一个xml对象相当于一个配置类;如下有两种方式一种是分别两个xml表示两个环境,第二种是一个xml里面配置两个并设置profile属性,如下就是第二种演示。

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        
        
    
        
        <beans profile="dev">
            <bean id="dateSour" class="part03.DevDateSour"/>
        beans>
        <beans profile="pro">
            <bean id="dateSour" class="part03.ProDateSour"/>
        beans>
    beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath:/profileContext.xml"})
    @ActiveProfiles("pro")
    public class ProfileXmlTest {
        @Autowired
        private DateSourceInterFace dateSource;
    
        @Test
        public void test01(){
            dateSource.printInfo();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    二、激活profile

    1、激活方式有如下几种:

    1、作为DispatcherServlet的初始化参数
    2、作为web应用的上下文参数
    3、作为环境变量
    4、使用@ActiveProfiles激活
    
    • 1
    • 2
    • 3
    • 4

    下面是web.xml中配置

    
    <context-param>
        <param-name>spring.profiles.defaultparam-name>
        <param-value>devparam-value>
    context-param>
    
    
    <servlet>
      <servlet-name>dispatcherservlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
        <init-param>
            <param-name>spring.profiles.activeparam-name>
            <param-value>proparam-value>
        init-param>
    servlet>
    
    
    -Dspring.profiles.active="pro"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    2、读取方式和顺序

    ①如果同时设置了 spring.profile.active=dev 和 spring.profile.default=pro ,只激活dev配置。
    ②如果没有配置spring.profile.active,只配置了spring.profile.default,才会读取default配置。
    ③那些没有定义在profile中的bean,任何时候都创建。

    三、条件化bean @Condition注解

    1、@Condition注解的作用

    @Condition注解的bean,只有满足实现 Condition 接口的 matches 方法才创建,否则忽略。

    @Configuration
    public class MagicConfig {
      @Bean
      //MagicExistsCondition类中match方法返回true就穿件如下bean
      @Conditional(MagicExistsCondition.class)
      public MagicBean magicBean() {
        return new MagicBean();
      }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    public class MagicExistsCondition implements Condition {
      @Override
      public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        return env.containsProperty("magic");
      }  
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2、Condition 接口使用

    Condition 接口的matches方法的两个参数

    public interface ConditionContext {
    //可以检查bean定义
        BeanDefinitionRegistry getRegistry();
    //检查bean是否存在,检查bean属性    
        ConfigurableListableBeanFactory getBeanFactory();
    //获取环境中存在或者值时多少    
        Environment getEnvironment();
    //获取resourceLoader加载的资源 
        ResourceLoader getResourceLoader();
    //返回累加器,并检查类是否存在       
        ClassLoader getClassLoader();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    AnnotatedTypeMetadata 可以检查@bean注解的方法上的其他注解信息。

    public interface AnnotatedTypeMetadata {
    //
    	boolean isAnnotated(String annotationName);
    	Map<String, Object> getAnnotationAttributes(String annotationName);
    	Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString);
    	MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName);
    	MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、@Profile注解源码

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Conditional(ProfileCondition.class)
    public @interface Profile {
    	/**
    	 * The set of profiles for which the annotated component should be registered.
    	 */
    	String[] value();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    class ProfileCondition implements Condition {
    
    	@Override
    	public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    		if (context.getEnvironment() != null) {
    	//获取@Profile注解的属性value值
    			MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
    			if (attrs != null) {
    				for (Object value : attrs.get("value")) {
    				//从环境中检查是否含有该vlaue值,有则激活该环境,并创建该bean对象
    					if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
    						return true;
    					}
    				}
    				return false;
    			}
    		}
    		return true;
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 相关阅读:
    共轭梯度法(CG)详解
    netsh命令
    5、K8s控制器- Deployment
    淘宝购物车分页方案研究
    OpenCV-最小外接圆cv::minEnclosingCircle
    2023年高教社杯数学建模国赛评审细则解读(附带分值设定)
    云安全系列3:如何构建云安全策略
    【Java系列】ArrayList
    Docker(狂神)
    如何在Window系统部署VisualSVN服务并结合cpolar实现无公网ip远程访问
  • 原文地址:https://blog.csdn.net/jue6628/article/details/125901143