高级组装

  1. 环境和 Profile 配置
    • 与环境相关的 Bean
      • JavaConfig:
        • @Profile("dev"): 只在 开发环境 创建这个 Bean
        • @Profile("prod"): 只在 产品环境 创建这个 Bean
      • XMLConfig:
        • <beans profile="dev"></beans>
    • Activating profiles
      • 使用 spring.profiles.default: <param-name>spring.profiles.default</param-name>
      • 使用 @ActiveProfiles("dev")
  2. 有条件性的 Bean
    • @Conditional(MagicExistsCondition.class)
      • 接口 Condition: boolean matches(ConditionContext ctxt, AnnotatedTypeMetadata metadata)
      • ConditionContext
        • 通过 getRegistry(). 检查 Bean 定义
        • 通过 getBeanFactory() 检查 Bean 存在
        • 通过 getEnvironment() 检查 环境变量的存在性
        • 通过 getResourceLoader() 读取和观察资源文件内容
        • 通过 getClassLoader() 加载和检查 类的存在
      • AnnotatedTypeMetadata
        • isAnnotated()
  3. 解决自动装载中的歧义性问题
    • 多个 Bean (@Component), NoUniqueBeanDefinitionException
    • 指定 Primary Bean
      • @Primary
      • <bean id="iceCream" class="com.desserteater.IceCream" primary="true" />
      • 可以指定多个 Primary Bean
    • @Qualifier("iceIcream")
      • 在指定 @Component 的地方声明 @Qualifier("cold")
      • 配合 @Autowired 使用
      • 配合 @Bean 使用
      • 创建多个 @Annotation
        • Java 不让同一个 @Annotation 使用多次
        • @Qualifier public @interface Code {}
        • @Soft, @Crispy, @Fruity
  4. Bean 的作用域
    • 默认全是 singletons
    • Spring 提供的作用域
      • Singletion
      • Prototype
      • Session
        • 购物车: @Scope(value=WebApplicationContext.SCOPE_SESSION, proxyMode=ScopedProxyMode.INTERFACES)
          • proxyMode=ScopedProxyMode.INTERFACES:
            • Spring 通过代理接口类来生成一个代理 Session 作用域的类
          • proxyMode=ScopedProxyMode.TARGET_CLASS:
            • Spring 使用 CGLib 生成一个具体类
        • XML
          • <bean id="card" class="com.myapp.ShoppingCart" scope="session"><aop:scoped-proxy /></bean>
            • 使用 CGLib 生成一个具体类
          • <aop:scoped-proxy proxy-target-class="false" />
            • 生成一个 接口
      • Request
    • @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    • <bean id="notepad" class="com.myapp.Notepad" scope="prototype" />
  5. 运行时注入
    • 属性 pleceholders
      • PropertySource("classpath:/com/soundsystem/app.properties")
      • env.getProperty("disc.title")
      • env.containsProperty("disc.title")
      • env.getPropertyAsClass("disc.class", CompactDisc.class)
    • The Spring Expression Language
      • 示例
        • #{ ... }
        • #{T(System).currentTimeMillis()}
          • T(): 把 java.lang.System 当做一种类型
          • T(java.lang.Math)
        • #{sgtPeppers.artist} 属性
        • #{artistSelector.selectArtist().toUpperCase()} 方法
          • #{artistSelector.selectArtist()?.toUpperCase()} 防止 NullPointerException
        • #{systemProperties['disc.title']}
        • #{3.14159} 字面量
        • #{'Hello'}
        • #{false}
        • 比较
          • #{counter.total == 100}
          • #{scoreboard.score > 1000 ? "Winner!" : "Loser"}
        • 正则
          • #{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.com'}
        • 集合
          • #{jukebox.songs[4].title}
          • #{'This is a test'[3]}
          • #{jukebox.songs.?[artist eq 'Aerosmith']}: 检查 songs 属性 artist 是否为 Aerosmith
          • #{jukebox.songs.^[artist eq 'Aerosmith']}: 选择第一个匹配的元素
          • #{jukebox.songs.$[artist eq 'Aerosmith']}: 选择最后一个匹配的元素
          • #{jukebox.songs.![title]}: 将 title 属性变为一个新的集合
      • JavaConfig
        • public BlankDisc( @Value("#{systemProperties['disc.title']}") String title) { this.title = title; }

results matching ""

    No results matching ""