国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Spring - 高級裝配

binta / 1549人閱讀

摘要:高級裝配條件化的自動裝配與歧義性的作用域表達式語言環境與可以為不同的環境提供不同的數據庫配置加密算法等注解可以在類級別和方法級別,沒有指定的始終都會被創建的方式配置不同環境所需要的數據庫配置會搭建一個嵌入式的數據庫模式定義在測試數據通過加

高級裝配

Spring profile

條件化的bean

自動裝配與歧義性

bean的作用域

Spring表達式語言

環境與profile

profile可以為不同的環境(dev、prod)提供不同的數據庫配置、加密算法等

@Profile注解可以在類級別和方法級別,沒有指定profile的bean始終都會被創建

XML的方式配置 datasource.xml

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jndi.JndiObjectFactoryBean;

/**
 * 不同環境所需要的數據庫配置
 */
public class DataSourceDemo {

    /**
     * EmbeddedDatabaseBuilder會搭建一個嵌入式的Hypersonic數據庫
     * 模式(schema)定義在schema.sql
     * 測試數據通過test-data.sql加載
     */
    @Bean(destroyMethod="shutdown")
    public DataSource dataSource_1(){
        return new EmbeddedDatabaseBuilder()
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
    }
    
    /**
     * 使用JNDI從容器中獲取一個DataSource
     */
    @Bean
    public DataSource dataSource_2(){
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/myDs");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        return (DataSource) jndiObjectFactoryBean.getObject();
    }
    
    /**
     * 配置DBCP的連接池
     */
    @Bean(destroyMethod="close")
    public DataSource dataSource(){
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setUrl("jdbc:h2:tcp://dbserver/~/test");
        dataSource.setDriverClassName("org.h2.Driver");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        dataSource.setInitialSize(20);
        dataSource.setMaxActive(30);
        return dataSource;
    }
    
}
激活profile

依賴屬性:spring.profiles.active和spring.profiles.default

作為DispatcherServlet的初始化參數

作為Web應用的上下文參數

作為JNDI條目

作為環境變量

作為JVM的系統屬性

在集成測試類上,使用@ActiveProfile注解設置

在web.xml中配置 見web.xml03

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;

/**
 * 不同環境數據源部署配置類
 *
 */
@Configuration
public class DataSourceConfig {

    /**
     * 為dev profile裝配的bean
     * @return
     */
    @Bean(destroyMethod="shutdown")
    @Profile("dev")
    public DataSource embeddedDataSource(){
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
    }
    
    /**
     * 為prod profile裝配的bean
     * @return
     */
    @Bean
    @Profile("prod")
    public DataSource jndiDataSource(){
        JndiObjectFactoryBean jndiObjectFactoryBean = 
                new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/myDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
        
        return (DataSource) jndiObjectFactoryBean.getObject();
    }
}
import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

/**
 * 開發環境部署配置類
 *
 */
@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {

    @Bean(destroyMethod="shutdown")
    public DataSource dataSource(){
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
    }
}
import org.junit.runner.RunWith;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * 使用profile進行測試
 * 當運行集成測試時,Spring提供了@ActiveProfiles注解,使用它來指定運行測試時要激活哪個profile
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={PersistenceConfig.class})
@ActiveProfiles("dev")
public class PersistenceTest {

}
條件化的bean

假設你希望一個或多個bean只有在應用的類路徑下包含特定庫時才創建

或者希望某個bean只有當另外某個特定的bean也聲明了之后才會創建

還可能要求只有某個特定的環境變量設置之后,才會創建某個bean

Spring4引入一個新的@Conditional注解,它可以用在帶有@Bean注解的方法上

例如,假設有個名為MagicBean的類,我們希望只有設置了magic環境屬性的時候,Spring才會實例化這個類

通過ConditionContext,可以:

借助getRegistry()返回的BeanDefinitionRegistry檢查bean定義

借助getBeanFactory()返回的ConfigurableListableBeanFactory檢查bean是否存在,甚至檢查bean的屬性

借助getEnvironment()返回的Environment檢查環境變量是否存在以及它的值是什么

讀取并探查getResourceLoader()返回的ResourceLoader所加載的資源

借助getClassLoader()返回的ClassLoader加載并檢查類是否存在

@Profile這個注解本身也使用了@Conditional注解,并且引用ProfileCondition作為條件

ProfileCondition會檢查value屬性,該屬性包含了bean的profile名稱。檢查profile是否激活

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class MagicExistsConditional implements Condition {

    /**
     * 方法簡單功能強大
     */
    @Override
    public boolean matches(ConditionContext ctxt, AnnotatedTypeMetadata metadata) {
        Environment env = ctxt.getEnvironment();
        //檢查magic屬性
        return env.containsProperty("magic");
    }

}
處理自動裝配的歧義

僅有一個bean匹配所需的結果時,自動裝配才是有效的,如果不僅有一個bean能夠匹配結果的話,這種歧義性會阻礙Spring自動裝配屬性、構造器參數或方法參數

標示首選(primary)的bean

@Component注解上加@Primary注解

在Java配置顯示聲明 中@Bean注解上加@Primary注解

XML配置bean primary="true"

限定自動裝配的bean

不止一個限定符時,歧義性問題依然存在

限定bean:在注解@Autowired上加@Qualifier("beanName")

限定符和注入的bean是耦合的,類名稱的任意改動都會導致限定失敗

* 創建自定義的限定符

* 在@Component注解上加@Qualifier("selfDefinedName")注解
* 可以在@Autowired上加@Qualifier("selfDefinedName")
* 也可以在Java配置顯示定義bean時,在@Bean注解上加@Qualifier("selfDefinedName")

使用自定義的限定符注解

如果有多個相同的限定符時,又會導致歧義性

在加一個@Qualifier注解:Java不允許在同一條目上出現相同的多個注解
(JDK8支持,注解本身在定義時帶有@Repeatable注解就可以,不過Spring的@Qualifier注解上沒有)

定義不同的注解,在注解上加@Qualifier,例如在bean上加@Cold和@Creamy(自定義注解)

bean的作用域

默認情況下,Spring應用上下文所有bean都是作為以單例(singleton)的形式創建的

Spring定義了多種作用域

單例(Singleton):在整個應用中,只創建bean的一個實例

原型(Prototype):每次注入或者通過Spring應用上下文獲取的時候,都會創建一個新的bean實例

會話(Session):在Web應用中,為每個會話創建一個bean實例

請求(Request):在Web應用中,每個請求創建一個bean實例

使用會話和請求作用域

購物車bean,會話作用域最合適,因為它與給定的用戶關聯性最大 例如:ShoppingCart

import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

/**
 * value=WebApplicationContext.SCOPE_SESSION值是session,每個會話會創建一個ShoppingCart
 * proxyMode=ScopedProxyMode.INTERFACES創建類的代理,確保當前購物車就是當前會話所對應的那一個,而不是其他用戶
 * 
 * XML的配置
 * 
 *         
 * 
 * 
 * 使用的是CGLib生成代理類
 */
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,
        proxyMode=ScopedProxyMode.INTERFACES)
public class ShoppingCart {

    
}
運行時值注入

Spring提供兩種運行的值注入

屬性占位符(Property placeholder)

Spring表達式語言(SpEL)

深入學習Spring的Environment

String getProperty(String key) 獲取屬性值

String getProperty(String key, String defaultValue) 獲取屬性值,不存在時返回給定默認值

T getProperty(String key, Class targetType); 獲取指定類型的屬性值

T getProperty(String key, Class targetType, T defaultValue); 獲取指定類型的屬性值,不存在時返回默認值

boolean containsProperty(String key); 檢查指定屬性值是否存在

String[] getActiveProfiles(); 返回激活profile名稱數組

String[] getDefaultProfiles(); 返回默認profile名稱數組

boolean acceptsProfiles(String... profiles); 如果environment支持給定profile的話,就返回true

解析屬性占位符

Spring一直支持將屬性定義到外部的屬性文件中,并使用占位符值將其插入到Spring bean中

在Spring裝配中,占位符的形式為使用"${...}"包裝的屬性名稱

在JavaConfig使用 @Value

在XML中

使用Spring表達式語言進行裝配

SpEl擁有特性:

使用bean的ID來引用bean

調用方法和訪問對象的屬性

對值進行算術、關系和邏輯運算

正則表達式匹配

c集合操作

Spring Security支持使用SpEL表達式定義安全限制規則

在Thymeleaf模板視圖中使用SpEL表達式引用模型數據

SpEL表達式要放到 "#{...}"之中:

        * #{1}         - 1
        * #{T(System).currentTimeMillis()}    -當前毫秒數
        * #{sgtPeppers.artist}          - ID為sgtPeppers的bean的artist屬性
        * #{systemProperties["disc.title"]}        -通過systemProperties對象引用系統屬性
* 表示字面值
    * 浮點數:#{3.14159}    科學計數法:#{9.87E4}        字符串:#{"hello"}    boolean類型:#{false}
* 引入bean、屬性和方法
        * #{sgtPeppers} -bean        #{sgtPeppers.artist} -屬性
        * #{sgtPeppers.selectArtist()} -方法        
        * #{sgtPeppers.selectArtist()?.toUpperCase()} -?.判斷非空情況調用toUpperCase方法
* 在表達式中使用類型
    * 如果要在SpEL中訪問類作用域的方法和常量的話,要依賴T()這個關鍵的運算符。
    * 表達Java的Math類    T(java.lang.Math)
    * 把PI屬性裝配待bean屬性    T(java.lang.Math).PI
    * 調用T()運算符所得到的靜態方法    T(java.lang.Math).random()
* SpEL運算符
        * 算術運算、比較運算、邏輯運算、條件運算、正則表達式、三元運算符
        * #{2 * T(java.lang.Math).PI * circle.radius}        -計算圓周長
        * #{T(java.lang.Math).PI * circle.radius ^ 2}        -計算圓面積
        * #{disc.title + "by" + disc.artist}                -String類型的連接操作
        * #{counter.total == 100}或#{counter.total eq 100} -比較運算
        * #{scoreboard.score > 1000 ? "Winner!" : "Losser"}    -三元運算
        * #{disc.title ?: "Rattle and Hum"}                -檢查null,使用默認值代替null
        * #{admin.email matches "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+.com"}        -匹配有效郵箱
        * #{jukebox.songs[4].title}    -計算ID為jukebox的bean的songs集合中第五個元素的title屬性
        * #{jukebox.songs[T(java.lang.Math).random() * jukebox.songs.size].title}        -獲取隨機歌曲的title
        * #{jukebox.songs.?[artist eq "Aerosmith"]}        -用來對集合過濾查詢
        * ‘.^[]’ 和 ‘.$[]’分別用來在集合中查詢第一個匹配項和最后一個匹配項
        * 投影運算符 (.![]),會從集合的每個成員中選擇特定的屬性放到另外一個集合中
引用:《Spring In Action 4》第3章

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71160.html

相關文章

  • Spring核心 Bean的高級裝配

    摘要:在集成測試時,通常想要激活的是開發環境的。因為沒有耦合類名,因此可以隨意重構的類名,不必擔心破壞自動裝配。在裝配中,占位符的形式為使用包裝的屬性名稱。參數裝配的是名為的屬性值。 環境與profile 配置profile bean 在3.1版本中,Spring引入了bean profile的功能。使用profile,首先將所有不同的bean定義整理到一個或多個profile之中,再將應用...

    forrest23 評論0 收藏0
  • Spring高級裝配之運行時注入

    摘要:原文地址運行時注入與硬編碼注入是相對的。硬編碼注入在編譯時就已經確定了,運行時注入則可能需要一些外部的參數來解決。提供的兩種在運行時求值的方式屬性占位符表達式語言注入外部的值使用注解可以引入文件,使用其中的值。 原文地址:http://blog.gaoyuexiang.cn/Sp... 運行時注入與硬編碼注入是相對的。硬編碼注入在編譯時就已經確定了,運行時注入則可能需要一些外部的參數來...

    ZweiZhao 評論0 收藏0
  • Spring - 裝配Bean

    摘要:裝配任何一個成功的應用都是由多個為了實現某個業務目標而相互協作的組件構成的創建應用對象之間協作關系的行為通常稱為裝配,這也是依賴注入配置的可選方案在中進行顯示配置在中進行顯示配置隱式的發現機制和自動裝配自動化裝配組件掃描會自動發現應用上下文 裝配Bean 任何一個成功的應用都是由多個為了實現某個業務目標而相互協作的組件構成的 創建應用對象之間協作關系的行為通常稱為裝配(wiring)...

    CNZPH 評論0 收藏0
  • 第三章 高級裝配

    摘要:注解只可以裝配只有一個實現類的例如下面的有三個實現類,自動裝配時,就會不知道選哪一個,因而會報錯誤。使用表達式語言進行裝配使用的來引用待補充實例調用方法和訪問對象的屬性對峙進行算數,關系和邏輯運算正則表達式匹配集合操作 完整代碼請見:https://github.com/codercuixi... 第一部分 @Profile注解的使用 環境與profile 是否啟用某個bean,常用于...

    only_do 評論0 收藏0
  • 面試被問爛的 Spring IOC(求求你別再問了)

    摘要:例如資源的獲取,支持多種消息例如的支持,對多了工具級別的支持等待。最上面的知道吧我就不講了。生命周期事件回調等。他支持不同信息源頭,支持工具類,支持層級容器,支持訪問文件資源,支持事件發布通知,支持接口回調等等。 廣義的 IOC IoC(Inversion of Control) 控制反轉,即不用打電話過來,我們會打給你。 兩種實現: 依賴查找(DL)和依賴注入(DI)。 IOC 和...

    denson 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<