• 第三章:高级装配



    3.1:Profile
    随着软件运行环境的变化程序需要加载的bean是不同的。例如开发环境使用的数据库和运行环境使用的数据库是不同的。Spring提供了profile,可以决定哪一种bean需要被使用。使用时只需要将不同的Bean指定不同的Profile,然后将需要的Profile激活即可。在Spring4.0中对@profile进行了重构,使其基于了@Conditional
    使用java配置声明Profile
    //开发时使用的Profile
    @configuration
    @Profile("dev") //这个配置类中的所有bean都属于名为dev的Profile(Spring3.1有的)。
    java配置类{}

    //测试时使用的Profile
    @configuration
    @Profile("qc")
    java配置类{}

    @Configuration
    java配置类{
    @Profile("dev") //指定当前的Bean属于devProfile(Spring3.2有的)
    @Bean
    Bean配置方法{}
    @Profile("qc")
    @Bean
    Bean配置方法{}
    }
    使用xml配置声明Profile
    <beans xmlns="http://...."
    profile = "dev"> //这个<beans>中包含的所有bean都属于devProfile
    <bean>....</bean>
    </beans>

    //使用嵌套<beans>的方法实现单独为bean配置
    <beans xmlns="http://...."> //这个<beans>中包含的所有bean都属于devProfile
    <beans profile="dev">
    <bean>...</bean>
    </beans>
    <beans profile="qc">
    <bean>...</bean>
    </beans>
    </beans>
    激活profile:
    激活profile需要配置的两个属性是:spring.profiles.active 和 spring.profiles.default。
    配置了active的profile为激活的,没有配置active是default生效,都没有配置都不生效。
    配置位置有很多(查资料)
    3.2:条件化Bean
    如果有一个Bean需要在另外一个特定的Bean声明后才创建。在Spring4.0提供了 @Conditional。它可以用在@Bean配置方法上,只有指定的条件成立时才会创建这个bean,否则忽略。
    例如:判断条件是环境变量中有“JAVA_HOME”。
    @Configuration
    java配置类{
    @Bean
    @Conditional(javaHomeExistsCondition.class) //配置比较类,这个类只需要实现Condition接口的matches方法即可。
    javaBean配置方法(){...}
    }
    public class javaHomeExistsCondition implements Condition{ //Condition接口中的matches方法返回Boolean值决定是否验证通过,matches的两个参数很有用
    public boolean matches(ConditionContext context , AnnotatedTypeMetadata metadata){
    Environment emv = context.getEnvironment();
    return env.containsProperty("JAVA_HOME");
    }
    }
    上面的matches方法非常简单,但是功能却非常强大。
    借助ConditionContext接口可以实现:
    getRegistry() 返回BeanDefinitionRegistry检查bean定义。
    getBeanFactory() 返回ConfigurableListableListableBeanFactory检查bean是否存在,探测bean的属性
    getEnvironment() 返回Environment检查环境变量
    getResourceLoader() 返回ResourceLoader读取并探测加载的资源
    getClassLoader() 返回ClassLoader检查类是否存在
    借助AnnotatedTypeMetadata接口可以检查带有@Bean注解的方法上还有什么其他注解
    3.3:处理自动转配的歧义性
    如果使用组件扫描自动装配Bean的话,Spring会寻找符合条件的Bean作为依赖注入,是当有多个Bean同时符合条件时,Spring不知道使用哪个Bean好。抛出异常:NoUniqueBeanDefinitionException。
    解决这个问题可以通过:1、标识首选的Bean 2、限定自动装配的Bean (使用方法查资料)
    3.4:Bean的作用域
    Spring应用上下文中的bean默认都是单例的,但是单例的bean是非常理想的,有时候使用的bean时易变得,会保持某一状态的。Spring还为Bean指定了别的作用域
    单例(Singleton) 在整个应用中只创建一个bean的实例。
    原型(Prototype) 每次注入或者在上下文中获取的时候都创建一个新的。
    会话(Session) Web应用中为每一个会话创建一个Bean实例
    请求(Request) Web应用中为每一个请求创建一个Bean实例

    配置bean的作用域
    使用组件扫描发现bean
    @Component
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public class xxx{...}
    在java配置中将bean
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public 类型 方法名(){...}
    使用xml配置bean
    <bean id = "xxx" class = "xxx.yyy" scope = "prototype"> </bean>
    使用会话和请求作用域
    将Bean声明为会话和请求作用域时有个问题:如果某些单例的bean依赖了这些bean,单例的bean创建的时候会话bean还不存在。Spring在这个问题上使用代理模式解决。
    因此声明会话或者请求作用域时需要加一个参数:
    @Scope(WebApplicationContext.SCOPE_SESSION , proxyMode = ScopedProxyMode.INTERFACES)
    使用方法???????????????????????
    3.5:运行时注入值
    有时候我们需要注入一个字面值,但是这个字面值目前是不确定的或者以后可能会改变,那么我们就需要在运行时才将这个值注入。Spring中解决方案有:1、使用属性占位符 2、使用Spring表达式语言(SpEl)
    注入外部值最简单的方法是声明属性源然后使用Environment来检索属性。
    @Configuration
    @PropertySource("classpath:/com/xxx/yyy/app.properties") //指定参数源
    public class 类名(){
    @Autowired
    Environment env; //Environment中重载的getProperty方法可以获取参数、获取参数并设置默认值、获取参数并解析为类。
    @Bean
    public 类型 方法名(){
    String aaa = env.getProperty("aaa"); //检索属性
    }
    }

    app.properties文件内容
    aaa = 需要的实际参数

    解析属性占位符
    Spring支持将属性定义到外部,并使用占位符将其插入到Spring bean中。在Spring装配中使用${}包装属性名称
    xml中:
    <bean id = "" class = "">
    <property name="" value = ${xxx.yyy}>
    </bean>
    具体使用方法(查资料)???????????????????
    使用SpEL表达式将外部值引入(查资料)??????????????????






  • 相关阅读:
    Mysql 库表
    Mysql (二)
    SQLAlchemy
    Mysql 测试题
    jquery
    抽屉 演示
    前端项目
    JavaScript
    Html Css  练习
    Pandas之DataFrame——Part 3
  • 原文地址:https://www.cnblogs.com/Xmingzi/p/8991001.html
Copyright © 2020-2023  润新知