Spring实战4 (3)高级装配

本章内容:

  • Spring profile
  • 条件化的bean声明
  • 自动化装配与歧义性
  • bean的作用域
  • Spring表达式语言
1.环境与profile

    在不同的环境中某个bean会有所不同(比如,DateSource),我们可以为不同的生产环境添加不同profile的设置文件,在构建项目的时候通过给spring.profiles.active属性不同的profile值来决定加载那个配置文件的信息来解决这个问题,同样在高级配置中spring给出了其他的解决方法(profile bean),我们可以选着性使用

    配置profile bean:

        Spring为环境相关的bean所提供的方案其实与构建时的方案没有太大的差别。当然,在这个过程中需要根据环境决定该创建哪个bean和不创建哪个bean。不过Spring并不是在构建的时候做出这样的决策,而是等到运行时再来确定。这样的结果就是同一个部署单元(可能是war文件,也可能是jar文件)能够适用于所有的环境,没有必要重新构建

        在Java配置中,可以使用@Profile注解指定某个bean属于哪一个profile

    激活profile:

        Spring在确定那个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default如果设置了spring.profiles.active属性的话,那么它的值就会用来确定那个profile是激活的。但如果没有设置spring.profiles.active属性的话,那Spring将会查找spring.profiles.default的值。都没设置的话,那就没有激活的profile,因此只会创建哪些没有定义在profile中的bean

        有多种方式来设置这两个属性:

            作为DispatcherServlet的初始化参数;
            作为Web应用的上下文参数;
            作为JNDI条目;
            作为环境变量;
            作为JVM的系统属性;

            在集成测试类上,使用@ActiveProfiles注解设置

 2.条件化的bean

     假设你希望一个或多个bean只有在应用的类路径下包含特定的库时才创建。或者我们希望某个bean只有当另外特定的bean也声明了之后才会创建。我们还可能要求只有某个特定的环境变量设置之后,才会创建某个bean。  

    @Conditional注解能够实现这个需求,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽略

    条件计算类需要事项Condition接口,该接口中只有一个matches()方法,方法中包含ConditionContext得到的Environment两个参数

    通过ConditionContext,我们可以做到如下几点:
        借助getRegistry()返回的BeanDefinitionRegistry检查bean定义;
        借助getBeanFactory()返回的ConfigurableListableBeanFactory检查bean是否存在,甚至探查bean的属性;
        借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是什么;
        读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;

        借助getClassLoader()返回的ClassLoader加载并检查类是否存在。

 3.处理自动装配的歧义性

        自动化装配时,仅有一个匹配所需的结构时,才是有小的。如果不仅有一个bean能够匹配结果的话,这种歧义性会阻碍Spring自动装配属性、构造器参数或方法参数,并抛出NoUniqueBeanDefinitionException。当发生歧义性的时候,我们可以将可选bean中的某一个设定为所选(primary)的bean,或者使用限定符(qualifiler)来帮助Spring将可选的bean的范围缩小到只有一个bean

    标识首选的bean:在bean类上,或者bean方法上添加@Promary

    限定自动装配的bean:与@Autowired组合是用@Qualifiler注解

 4.bean的作用域    

    在默认的情况下,Spring应用上下文中所有bean都是作为已单例(singleton)的形式创建的。也就是说,不管给定的一个bean被注入到其他bean多少次,每次所注入的都是同一个实例

    有时候,可能会发现,你所使用的类是易变的(mutable),它们会保持一些状态,因此重用是不安全的。在这种情况下,将class声明为单例的bean就不是什么好主意了,因为对象会被污染,稍后重用的时候会出现意想不到的问题

    Spring定义了多种作用域,可以基于这些作用域创建bean,包括:
        单例(Singleton):在整个应用中,只创建bean的一个实例。
        原型(Prototype):每次注入或者通过Spring应用上下文获取的时候,都会创建一个新的bean实例。
        会话(Session):在Web应用中,为每个会话创建一个bean实例。
        请求(Rquest):在Web应用中,为每个请求创建一个bean实例。

    单例是默认的作用域,但是正如之前所述,对于易变的类型,这并不合适。如果选择其他的作用域,要使用@Scope注解,它可以与@Commonent或@Bean一起使用

 5.运行时值注入

    当讨论依赖注入的时候,我们通常所讨论的是将一个bean引用注入到另一个bean的属性或构造器参数中。它通常来讲的是将一个对象与另一个对象进行关联。但是bean装配的另外一个方面是将一个值注入到bean的属性或者构造参数中

    Spring提供了两种在运行时求值的方式:

  • 属性占位符
  • Spring表达式语言  

     在Spring中,处理外部值最简单方式就是声明属性源并通过Spring的Environment来检索属性     

    

    解析属性占位符:

        

    使用Spring表达式语言进行装配:

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值