成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring - 高級裝配

binta / 1562人閱讀

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

高級裝配

Spring profile

條件化的bean

自動裝配與歧義性

bean的作用域

Spring表達式語言

環(huán)境與profile

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

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

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;

/**
 * 不同環(huán)境所需要的數(shù)據(jù)庫配置
 */
public class DataSourceDemo {

    /**
     * EmbeddedDatabaseBuilder會搭建一個嵌入式的Hypersonic數(shù)據(jù)庫
     * 模式(schema)定義在schema.sql
     * 測試數(shù)據(jù)通過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的初始化參數(shù)

作為Web應(yīng)用的上下文參數(shù)

作為JNDI條目

作為環(huán)境變量

作為JVM的系統(tǒng)屬性

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

在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;

/**
 * 不同環(huán)境數(shù)據(jù)源部署配置類
 *
 */
@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;

/**
 * 開發(fā)環(huán)境部署配置類
 *
 */
@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進行測試
 * 當(dāng)運行集成測試時,Spring提供了@ActiveProfiles注解,使用它來指定運行測試時要激活哪個profile
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={PersistenceConfig.class})
@ActiveProfiles("dev")
public class PersistenceTest {

}
條件化的bean

假設(shè)你希望一個或多個bean只有在應(yīng)用的類路徑下包含特定庫時才創(chuàng)建

或者希望某個bean只有當(dāng)另外某個特定的bean也聲明了之后才會創(chuàng)建

還可能要求只有某個特定的環(huán)境變量設(shè)置之后,才會創(chuàng)建某個bean

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

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

通過ConditionContext,可以:

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

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

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

讀取并探查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匹配所需的結(jié)果時,自動裝配才是有效的,如果不僅有一個bean能夠匹配結(jié)果的話,這種歧義性會阻礙Spring自動裝配屬性、構(gòu)造器參數(shù)或方法參數(shù)

標(biāo)示首選(primary)的bean

@Component注解上加@Primary注解

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

XML配置bean primary="true"

限定自動裝配的bean

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

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

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

* 創(chuàng)建自定義的限定符

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

使用自定義的限定符注解

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

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

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

bean的作用域

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

Spring定義了多種作用域

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

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

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

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

使用會話和請求作用域

購物車bean,會話作用域最合適,因為它與給定的用戶關(guān)聯(lián)性最大 例如: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,每個會話會創(chuàng)建一個ShoppingCart
 * proxyMode=ScopedProxyMode.INTERFACES創(chuàng)建類的代理,確保當(dāng)前購物車就是當(dāng)前會話所對應(yīng)的那一個,而不是其他用戶
 * 
 * XML的配置
 * 
 *         
 * 
 * 
 * 使用的是CGLib生成代理類
 */
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,
        proxyMode=ScopedProxyMode.INTERFACES)
public class ShoppingCart {

    
}
運行時值注入

Spring提供兩種運行的值注入

屬性占位符(Property placeholder)

Spring表達式語言(SpEL)

深入學(xué)習(xí)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名稱數(shù)組

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

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

解析屬性占位符

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

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

在JavaConfig使用 @Value

在XML中

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

SpEl擁有特性:

使用bean的ID來引用bean

調(diào)用方法和訪問對象的屬性

對值進行算術(shù)、關(guān)系和邏輯運算

正則表達式匹配

c集合操作

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

在Thymeleaf模板視圖中使用SpEL表達式引用模型數(shù)據(jù)

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

        * #{1}         - 1
        * #{T(System).currentTimeMillis()}    -當(dāng)前毫秒數(shù)
        * #{sgtPeppers.artist}          - ID為sgtPeppers的bean的artist屬性
        * #{systemProperties["disc.title"]}        -通過systemProperties對象引用系統(tǒng)屬性
* 表示字面值
    * 浮點數(shù):#{3.14159}    科學(xué)計數(shù)法:#{9.87E4}        字符串:#{"hello"}    boolean類型:#{false}
* 引入bean、屬性和方法
        * #{sgtPeppers} -bean        #{sgtPeppers.artist} -屬性
        * #{sgtPeppers.selectArtist()} -方法        
        * #{sgtPeppers.selectArtist()?.toUpperCase()} -?.判斷非空情況調(diào)用toUpperCase方法
* 在表達式中使用類型
    * 如果要在SpEL中訪問類作用域的方法和常量的話,要依賴T()這個關(guān)鍵的運算符。
    * 表達Java的Math類    T(java.lang.Math)
    * 把PI屬性裝配待bean屬性    T(java.lang.Math).PI
    * 調(diào)用T()運算符所得到的靜態(tài)方法    T(java.lang.Math).random()
* SpEL運算符
        * 算術(shù)運算、比較運算、邏輯運算、條件運算、正則表達式、三元運算符
        * #{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章

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/71160.html

相關(guān)文章

  • Spring核心 Bean的高級裝配

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

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

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

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

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

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

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

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

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

    denson 評論0 收藏0

發(fā)表評論

0條評論

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