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

資訊專欄INFORMATION COLUMN

第三章 高級(jí)裝配

only_do / 2177人閱讀

摘要:注解只可以裝配只有一個(gè)實(shí)現(xiàn)類的例如下面的有三個(gè)實(shí)現(xiàn)類,自動(dòng)裝配時(shí),就會(huì)不知道選哪一個(gè),因而會(huì)報(bào)錯(cuò)誤。使用表達(dá)式語言進(jìn)行裝配使用的來引用待補(bǔ)充實(shí)例調(diào)用方法和訪問對(duì)象的屬性對(duì)峙進(jìn)行算數(shù),關(guān)系和邏輯運(yùn)算正則表達(dá)式匹配集合操作

完整代碼請(qǐng)見:https://github.com/codercuixi...

第一部分 @Profile注解的使用

環(huán)境與profile 是否啟用某個(gè)bean,常用于數(shù)據(jù)庫bean
通過profile啟用不同的bean,特別是對(duì)于各種不同的數(shù)據(jù)庫(開發(fā)線,測(cè)試線,正式線),尤其管用。
1.1第一步 配置profile bean。通過@Profile修飾類或者方法名,來表明這個(gè)Bean是可以動(dòng)態(tài)啟動(dòng)與否的

package com.myapp;

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;

import javax.sql.DataSource;

@Configuration
public class DataSourceConfig {

    @Bean(destroyMethod = "shutdown")
    @Profile("dev")
    public DataSource embeddedDataSource() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:schema.sql")
                .addScript("classpath:test-data.sql")
                .build();
    }

    @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();
    }
}

1.2.第二步,激活profile。
通過@ActiveProfile來激活指定的Profile,啟用指定的數(shù)據(jù)庫Bean。

package profiles;

import static org.junit.Assert.*;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.myapp.DataSourceConfig;

public class DataSourceConfigTest {

  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes=DataSourceConfig.class)
  @ActiveProfiles("dev")
  public static class DevDataSourceTest {
    @Autowired
    private DataSource dataSource;
    
    @Test
    public void shouldBeEmbeddedDatasource() {
      assertNotNull(dataSource);
      JdbcTemplate jdbc = new JdbcTemplate(dataSource);
      List results = jdbc.query("select id, name from Things", new RowMapper() {
        @Override
        public String mapRow(ResultSet rs, int rowNum) throws SQLException {
          return rs.getLong("id") + ":" + rs.getString("name");
        }
      });
      
      assertEquals(1, results.size());
      assertEquals("1:A", results.get(0));
    }
  }

  @RunWith(SpringJUnit4ClassRunner.class)
  @ContextConfiguration(classes=DataSourceConfig.class)
  @ActiveProfiles("prod")
  public static class ProductionDataSourceTest {
    @Autowired
    private DataSource dataSource;
    
    @Test
    public void shouldBeEmbeddedDatasource() {
      // should be null, because there isn"t a datasource configured in JNDI
      assertNull(dataSource);
    }
  }
}

1.3.通過兩個(gè)參數(shù)激活profile
spring.profiles.active和spring.profiles.default,優(yōu)先使用前者的配置。
設(shè)置這兩個(gè)參數(shù)的方式有如下幾種:(待補(bǔ)充完整)

作為DIspatcherServlet的初始化參數(shù)

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

作為JNDI條目

作為環(huán)境變量

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

在集成測(cè)試類上,使用@ActiveProfile注解設(shè)置。(也就是上面第二步演示的)

第二部分 條件化的bean

通過@Conditional, 可以用到Bean上,當(dāng)條件為true,則創(chuàng)建該Bean;否則則不創(chuàng)建。
主要分為一下三步
1.像往常一樣定義Bean的POJO類
2.編寫org.springframework.context.annotation.Condition接口的類MagicExistsCondition,用來創(chuàng)建是否創(chuàng)建該Bean
3.將@Conditional(MagicExistsCondition.class)應(yīng)用到Bean的JavaConfig上。

package conditional.habuma.restfun;

public class MagicBean {
}
package conditional.habuma.restfun;

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

/**
 * * @Author: cuixin
 * * @Date: 2018/8/30 18:32
 */
public class MagicExistsCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment environment = context.getEnvironment();
        return environment.containsProperty("magic");
    }
}
package conditional.habuma.restfun;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

/**
 * * @Author: cuixin
 * * @Date: 2018/8/30 18:32
 */
@Configuration
public class MagicConfig {

    @Bean
    @Conditional(MagicExistsCondition.class)
    public MagicBean magicBean(){
        return new MagicBean();
    }
}

由于實(shí)現(xiàn)了match方法中帶有兩個(gè)參數(shù),我們可以通過這兩個(gè)參數(shù)做到什么呢?
ConditionContext接口的方法

public interface ConditionContext {

    /**
     * 返回BeanDefinitionRegistry,可用來判斷Bean是否定義
     */
    BeanDefinitionRegistry getRegistry();

    /**
     * 返回ConfigurableListableBeanFactory,可用來檢查Bean是否存在,甚至探查Bean的屬性
     */
    @Nullable
    ConfigurableListableBeanFactory getBeanFactory();

    /**
     * 返回Environment,可用來判斷環(huán)境變量是否存在,且獲取環(huán)境變量的值
     */
    Environment getEnvironment();

    /**
     *返回ResourceLoader,可用來讀取或探查已經(jīng)加載的資源
     */
    ResourceLoader getResourceLoader();

    /**
     * 返回ClassLoader,可用來加載類或判斷類是否存在
     */
    @Nullable
    ClassLoader getClassLoader();

}

AnnotatedTypeMetadata 用來獲取注解相關(guān)信息

public interface AnnotatedTypeMetadata {

    
    boolean isAnnotated(String annotationName);
    
    @Nullable
    Map getAnnotationAttributes(String annotationName);
    
    @Nullable
    Map getAnnotationAttributes(String annotationName, boolean classValuesAsString);
    
    @Nullable
    MultiValueMap getAllAnnotationAttributes(String annotationName);
    
    @Nullable
    MultiValueMap getAllAnnotationAttributes(String annotationName, boolean classValuesAsString);

第三部分 處理自動(dòng)裝配的歧義性。

3.1@AutoWired 注解只可以裝配只有一個(gè)實(shí)現(xiàn)類的Bean
例如下面的Dessert有三個(gè)實(shí)現(xiàn)類,自動(dòng)裝配時(shí),Spring就會(huì)不知道選哪一個(gè),因而會(huì)報(bào)NoUniqueBeanDefinitionException錯(cuò)誤。

public interface Dessert {
}
@Component
public class Cake implements Dessert {
}
@Component
public class Cookies implements Dessert {
}
@Component
public class IceCream implements Dessert {
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CakeConfig.class)
public class CakeTest {
    @Autowired
    private Dessert dessert;//Spring: emmm.... I don"t which one to choose
    @Test
    public void getDessert(){
        assertNotNull(dessert);
    }
}

3.2 @Primary 可以指定某個(gè)實(shí)現(xiàn)類作為優(yōu)先Bean創(chuàng)建
給蛋糕加個(gè)@Primary,表明首選蛋糕作為首選項(xiàng)。然后在執(zhí)行Test,發(fā)現(xiàn)就不抱錯(cuò)了。
@Primary可以配合@Component, @Bean, @Autowired使用。

@Component
@Primary
public class Cake implements Dessert {
}

3.3 @Qualifie將使用的Bean限定到具體的實(shí)現(xiàn)類
由于@Qualifier是基于字符串去匹配Bean id的,所以你修改了類名就可能導(dǎo)致找不到對(duì)應(yīng)的Bean了。但我嘗試了一下,如果使用IDEA的Refactor->Rename,會(huì)幫我們自動(dòng)更改多處的。
@Qualifie可以配合@Component, @Bean, @Autowired使用。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = CakeConfig.class)
public class CakeTest {
    @Autowired
    @Qualifier("cookies")
    private Dessert dessert;
    @Test
    public void getDessert(){
        assertNotNull(dessert);
    }
}

Spring實(shí)戰(zhàn)中,為了解決@Qualifier“不夠用”,拼命地建立自定義注解,我感覺是沒有必要,有點(diǎn)畫蛇添足的感覺。

四. bean的作用域

四種不同的作用域
單例(Singleton默認(rèn)):在整個(gè)應(yīng)用中,只創(chuàng)建bean的一個(gè)實(shí)例。
比如

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public Notepad notepad() {
        return new Notepad();
    }

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

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Notepad notepad() {
        return new Notepad();
    }

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

    @Bean
    @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Notepad notepad() {
        return new Notepad();
    }

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

    @Bean
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public Notepad notepad() {
        return new Notepad();
    }

這里需要注意的是proxyMode這個(gè)屬性。(TODO:通過例子加深理解)
當(dāng)值為ScopedProxyMode.TARGET_CLASS時(shí),表示的該bean類型是具體類,只能使用CGLib來生成基于類的代理。
當(dāng)值為ScopedProxyMode.INTERFACES時(shí)。

五.運(yùn)行時(shí)注入

1.使用@PropertySource, @Environment注入外部值

app.properties的內(nèi)容
disc.title=Sgt. Peppers Lonely Hearts Club Band
disc.artist=The Beatles

public class BlankDisc {
    private final String title;
    private final String artist;
    public BlankDisc(String title, String artist){
        this.title = title;
        this.artist = artist;
    }
    public String getArtist() {
        return artist;
    }

    public String getTitle() {
        return title;
    }
}

@Configuration
@PropertySource("classpath:/externals/com/soundsystem/app.properties")
public class EnvironmentConfig {
    @Autowired
    private Environment env;

    @Bean
    public BlankDisc blankDisc(){
        return new BlankDisc(env.getProperty("disc.title"), env.getProperty("disc.artist"));
    }

}

另外Environment的getProperty有4個(gè)重載方式可以選擇

String getProperty(String key); //獲取指定key的內(nèi)容;如果找不到key就返回null
String getProperty(String key, String defaultValue);//獲取指定key的內(nèi)容;如果找不到key,就返回默認(rèn)值
 T getProperty(String key, Class targetType);//targetType用于說明該key的值類型
 T getProperty(String key, Class targetType, T defaultValue);


2.屬性占位符
${...}表示屬性占位符,常配合@Value使用,舉個(gè)栗子。

    @Bean
    public BlankDisc blankDisc2(@Value("${disc.title}") String title, @Value("${disc.artist}")String artist){
        return new BlankDisc(title, artist);

    }
3.使用Spring表達(dá)式語言進(jìn)行裝配

1.使用bean的id來引用Bean TODO 待補(bǔ)充實(shí)例
2.調(diào)用方法和訪問對(duì)象的屬性
3.對(duì)峙進(jìn)行算數(shù),關(guān)系和邏輯運(yùn)算
4.正則表達(dá)式匹配
5.集合操作

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

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

相關(guān)文章

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

    摘要:在集成測(cè)試時(shí),通常想要激活的是開發(fā)環(huán)境的。因?yàn)闆]有耦合類名,因此可以隨意重構(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入門看這一篇就夠了

    摘要:甲乙交易活動(dòng)不需要雙方見面,避免了雙方的互不信任造成交易失敗的問題。這就是的核心思想。統(tǒng)一配置,便于修改。帶參數(shù)的構(gòu)造函數(shù)創(chuàng)建對(duì)象首先,就要提供帶參數(shù)的構(gòu)造函數(shù)接下來,關(guān)鍵是怎么配置文件了。 前言 前面已經(jīng)學(xué)習(xí)了Struts2和Hibernate框架了。接下來學(xué)習(xí)的是Spring框架...本博文主要是引入Spring框架... Spring介紹 Spring誕生: 創(chuàng)建Spring的...

    superw 評(píng)論0 收藏0
  • Spring - 高級(jí)裝配

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

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

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

    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

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

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<