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

資訊專欄INFORMATION COLUMN

第三章 高級裝配

only_do / 2170人閱讀

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

完整代碼請見:https://github.com/codercuixi...

第一部分 @Profile注解的使用

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

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.通過兩個參數(shù)激活profile
spring.profiles.active和spring.profiles.default,優(yōu)先使用前者的配置。
設置這兩個參數(shù)的方式有如下幾種:(待補充完整)

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

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

作為JNDI條目

作為環(huán)境變量

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

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

第二部分 條件化的bean

通過@Conditional, 可以用到Bean上,當條件為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)應用到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();
    }
}

由于實現(xiàn)了match方法中帶有兩個參數(shù),我們可以通過這兩個參數(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);

第三部分 處理自動裝配的歧義性。

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

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

@Component
@Primary
public class Cake implements Dessert {
}

3.3 @Qualifie將使用的Bean限定到具體的實現(xiàn)類
由于@Qualifier是基于字符串去匹配Bean id的,所以你修改了類名就可能導致找不到對應的Bean了。但我嘗試了一下,如果使用IDEA的Refactor->Rename,會幫我們自動更改多處的。
@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實戰(zhàn)中,為了解決@Qualifier“不夠用”,拼命地建立自定義注解,我感覺是沒有必要,有點畫蛇添足的感覺。

四. bean的作用域

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

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

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

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

會話(Session):在web應用中,為每個會話創(chuàng)建一個bean實例, 舉個例子:

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

請求(Request):在web應用中,為每個請求創(chuàng)建一個bean實例,舉個栗子:

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

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

五.運行時注入

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個重載方式可以選擇

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


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

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

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

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

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

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

相關(guān)文章

  • Spring核心 Bean的高級裝配

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

    forrest23 評論0 收藏0
  • Spring入門看這一篇就夠了

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

    superw 評論0 收藏0
  • Spring - 高級裝配

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

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

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

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

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

    CNZPH 評論0 收藏0

發(fā)表評論

0條評論

only_do

|高級講師

TA的文章

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