成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Spring - 高級(jí)裝配

binta / 1618人閱讀

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

高級(jí)裝配

Spring profile

條件化的bean

自動(dòng)裝配與歧義性

bean的作用域

Spring表達(dá)式語(yǔ)言

環(huán)境與profile

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

@Profile注解可以在類級(jí)別和方法級(jí)別,沒(méi)有指定profile的bean始終都會(huì)被創(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ù)庫(kù)配置
 */
public class DataSourceDemo {

    /**
     * EmbeddedDatabaseBuilder會(huì)搭建一個(gè)嵌入式的Hypersonic數(shù)據(jù)庫(kù)
     * 模式(schema)定義在schema.sql
     * 測(cè)試數(shù)據(jù)通過(guò)test-data.sql加載
     */
    @Bean(destroyMethod="shutdown")
    public DataSource dataSource_1(){
        return new EmbeddedDatabaseBuilder()
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
    }
    
    /**
     * 使用JNDI從容器中獲取一個(gè)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)屬性

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

在web.xml中配置 見(jiàn)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;

/**
 * 開(kāi)發(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進(jìn)行測(cè)試
 * 當(dāng)運(yùn)行集成測(cè)試時(shí),Spring提供了@ActiveProfiles注解,使用它來(lái)指定運(yùn)行測(cè)試時(shí)要激活哪個(gè)profile
 *
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={PersistenceConfig.class})
@ActiveProfiles("dev")
public class PersistenceTest {

}
條件化的bean

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

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

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

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

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

通過(guò)ConditionContext,可以:

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

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

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

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

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

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

ProfileCondition會(huì)檢查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 {

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

}
處理自動(dòng)裝配的歧義

僅有一個(gè)bean匹配所需的結(jié)果時(shí),自動(dòng)裝配才是有效的,如果不僅有一個(gè)bean能夠匹配結(jié)果的話,這種歧義性會(huì)阻礙Spring自動(dòng)裝配屬性、構(gòu)造器參數(shù)或方法參數(shù)

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

@Component注解上加@Primary注解

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

XML配置bean primary="true"

限定自動(dòng)裝配的bean

不止一個(gè)限定符時(shí),歧義性問(wèn)題依然存在

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

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

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

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

使用自定義的限定符注解

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

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

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

bean的作用域

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

Spring定義了多種作用域

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

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

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

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

使用會(huì)話和請(qǐng)求作用域

購(gòu)物車bean,會(huì)話作用域最合適,因?yàn)樗c給定的用戶關(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,每個(gè)會(huì)話會(huì)創(chuàng)建一個(gè)ShoppingCart
 * proxyMode=ScopedProxyMode.INTERFACES創(chuàng)建類的代理,確保當(dāng)前購(gòu)物車就是當(dāng)前會(huì)話所對(duì)應(yīng)的那一個(gè),而不是其他用戶
 * 
 * XML的配置
 * 
 *         
 * 
 * 
 * 使用的是CGLib生成代理類
 */
@Component
@Scope(value=WebApplicationContext.SCOPE_SESSION,
        proxyMode=ScopedProxyMode.INTERFACES)
public class ShoppingCart {

    
}
運(yùn)行時(shí)值注入

Spring提供兩種運(yùn)行的值注入

屬性占位符(Property placeholder)

Spring表達(dá)式語(yǔ)言(SpEL)

深入學(xué)習(xí)Spring的Environment

String getProperty(String key) 獲取屬性值

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

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

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

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

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

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

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

解析屬性占位符

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

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

在JavaConfig使用 @Value

在XML中

使用Spring表達(dá)式語(yǔ)言進(jìn)行裝配

SpEl擁有特性:

使用bean的ID來(lái)引用bean

調(diào)用方法和訪問(wèn)對(duì)象的屬性

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

正則表達(dá)式匹配

c集合操作

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

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

SpEL表達(dá)式要放到 "#{...}"之中:

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/71160.html

相關(guān)文章

  • Spring核心 Bean的高級(jí)裝配

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

    forrest23 評(píng)論0 收藏0
  • Spring高級(jí)裝配之運(yùn)行時(shí)注入

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

    ZweiZhao 評(píng)論0 收藏0
  • Spring - 裝配Bean

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

    CNZPH 評(píng)論0 收藏0
  • 第三章 高級(jí)裝配

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

    only_do 評(píng)論0 收藏0
  • 面試被問(wèn)爛的 Spring IOC(求求你別再問(wèn)了)

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

    denson 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<