Springboot学習2——IoC(下)

7838 ワード

六、条件付き組立Bean
Beanを初期化する前に、ベース属性をいくつか検証し、検証を満たさない場合はデータソースをアセンブリしません.
@Conditional注記+Conditionインタフェース(org.springframework.context.annotation.Condition)を実装するクラス.例:
属性を使用したデータベース接続プールの初期化:@Conditional注記が追加され、クラスDatabaseConditionalが構成されています.
@Bean(name = "dataSource", destroyMethod = "close")
@Conditional(DatabaseConditional.class)
public DataSource getDataSource(
        @Value("${database.driverName}") String driver,
        @Value("${database.url}") String url,
        @Value("${database.username}") String username, 
        @Value("${database.password}") String password
        ) {
    Properties props = new Properties();
    props.setProperty("driver", driver);
    props.setProperty("url", url);
    props.setProperty("username", username);
    props.setProperty("password", password);
    DataSource dataSource = null;
    try {
        dataSource = BasicDataSourceFactory.createDataSource(props);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return dataSource;
}

DatabaseConditionalクラス:Conditionインタフェースを実装し、matchesメソッドを書き換え、matchesメソッドはまずコンテキスト環境を読み取り、対応するデータベース情報が構成されているかどうかを判定します.これらがすべて構成されている場合はtrueを返します.このときSpringはデータベース接続プールのBeanをアセンブリします.そうしないとアセンブリされません.
public class DatabaseConditional implements Condition {

    /**
     *        
     *
     * @param context      
     * @param metadata         
     * @return true  Bean,     
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //       
        Environment env = context.getEnvironment();
        //                   
        return env.containsProperty("database.driverName") 
                && env.containsProperty("database.url")
                && env.containsProperty("database.username") 
                && env.containsProperty("database.password");
    }
}

七、Beanの役割ドメイン
IoCコンテナの最上位インタフェースBeanFactoryを紹介すると、isSingletonとisPrototypeの2つの方法が見られます.ここで、isSingletonメソッドがtrueを返すと、BeanはIoCコンテナに一例として存在し、これもSpring IoCコンテナのデフォルト値である.isPrototypeメソッドがtrueを返す場合、IoCコンテナはBeanを取得するたびに新しいBeanを作成します.これはSpring Beanの役割ドメインの問題です.
一般的な容器では、Beanには、SingletonとPrototypeの2つの役割ドメインが存在し、Java EEはインターネットで広く使用されているが、Webコンテナでは、ページ(page)、リクエスト(request)、セッション(session)、アプリケーション(application)の4つの役割ドメインが存在する.ページ(page)については、JSPの現在のページに対する役割ドメインであり、Springはサポートできない.
次に,単一例(Singleton)とプロトタイプ(Prototype)の区別定義役割ドメインクラスについて検討する.
@Component
// @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class ScopeBean {
}

スコープのテスト
AnnotationConfigApplicationContext ctx 
    = new AnnotationConfigApplicationContext(AppConfig.class);
ScopeBean scopeBean1 = ctx.getBean(ScopeBean.class);
ScopeBean scopeBean2 = ctx.getBean(ScopeBean.class);
System.out.println(scopeBean1 == scopeBean2);

Springスコープのテストコメントが追加された場合、デフォルトでは単一の例、結果trueです.注記を付けない場合、IoCコンテナはBeanを取得するたびに、新しいBeanのインスタンスを呼び出し元に返し、結果falseを返します.ここでConfigurableBeanFactoryは、単一の例(SCOPE_SINGLETON)とプロトタイプ(SCOPE_PROTOTYPE)の2つの役割ドメインのみを選択できます.
Spring MVC環境であれば、WebApplicationContextを使用して、要求(SCOPE_REQUEST)、セッション(SCOPE_SESSION)、アプリケーション(SCOPE_APPLICATION)などの他の役割ドメインを定義することもできます.
@Component@Scope(WebApplicationContext.SCOPE_REQUEST)public class ScopeBean{}このように同じリクエスト範囲内でこのBeanを取得すると、同じBeanを共有するだけで、2回目のリクエストで新しいBeanが生成されます.したがって、2つの異なる要求は、異なるインスタンスのBeanを得ることになる.
八、@Profileを使う
Profileメカニズム:各環境間の切り替えを実現します.
dev_が存在すると仮定spring_bootとtest_spring_boot 2つのデータベースで、注記@Profileを使用して2つのBeanを定義できます.
@Bean(name = "dataSource", destroyMethod = "close")
@Profile("dev")
public DataSource getDevDataSource() {
    Properties props = new Properties();
    props.setProperty("driver", "com.mysql.jdbc.Driver");
    props.setProperty("url", "jdbc:mysql://localhost:3306/dev_spring_boot");
    props.setProperty("username", "root");
    props.setProperty("password", "123456");
    DataSource dataSource = null;
    try {
        dataSource = BasicDataSourceFactory.createDataSource(props);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return dataSource;
}
@Bean(name = "dataSource", destroyMethod = "close")
@Profile("test")
public DataSource getTestDataSource() {
    Properties props = new Properties();
    props.setProperty("driver", "com.mysql.jdbc.Driver");
    props.setProperty("url", "jdbc:mysql://localhost:3306/test_spring_boot");
    props.setProperty("username", "root");
    props.setProperty("password", "123456");
    DataSource dataSource = null;
    try {
        dataSource = BasicDataSourceFactory.createDataSource(props);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return dataSource;
}

Springに2つのパラメータが存在して起動プロファイルメカニズムを変更します.両方のプロパティが構成されていない場合、SpringはProfileメカニズムを起動しません.つまり、@ProfileでマークされたBeanはSpringによってIoCコンテナに組み込まれません.
一つはspringです.profiles.一つはspringですprofiles.default.
2つの属性に優先度がある、springがあるか否かを判定する.profiles.Activeの構成後、springを検索します.profiles.default構成の
Java起動プロジェクトでは、次の構成でProfileメカニズムを起動できます:JAVA_OPTS="-Dspring.profiles.active=dev"
九、XML構成Beanの導入
注記@ImportResource:Beanをロードするために、対応するXMLファイルを導入できます.Dubbo,CatのようなフレームワークはSpringのXML方式に基づいて開発される場合がありますが、この場合はXML方式を導入して構成する必要があります.まずPOJOを構築します.
public class Squirrel implements Animal {
    @Override
    public void use() {
        System.out.println("        ");
    }
}

なお、このPOJOが存在するパケットは@ComponentScanで定義されたスキャンパケットcomではない.springboot.chapter3.*内であり、@Componentと表記されていないため、スキャンメカニズムに組み込まれません.ここでは、XMLを使用して組み立てるので、XMLファイルを定義してXML構成POJO-spring-otherを使用することができます.xml

       


Javaプロファイルに直接読み込むことができ、XML定義のBeanをアセンブリできます.
@Configuration
@ComponentScan(basePackages = "com.springboot.chapter3.*")
@ImportResource(value = {"classpath:spring-other.xml"})
public class AppConfig {
......
}

これにより対応するXMLを導入することができ,XML定義のBeanもIoCコンテナに組み込むことができる.
十、Spring ELを使う
Spring ELはBeanをよりよく組み立てるためにより強力な演算規則を持っている.
1.プロパティ・ファイルの値を読み込みます.@Value ${......} コンテキストのプロパティ値を読み込みます.たとえば、@Value(「${database.driverName}」)String driver
2.@Valueはまたメソッドを呼び出すことができ、#{......}を使用してSpring式を有効にすることを表します.これは演算機能を有します.たとえば、Beanの初期化時間を記録します.@Value(#{T(System).currentTimeMillis()}))private Long initTime=null;
ここでT(…)は導入クラスを表す.Systemはjavaです.lang.*パッケージのクラスです.これはJavaがデフォルトでロードしたパッケージです.そのため、フルリミット名を書く必要はありません.他のパッケージであれば、クラスを参照するにはフルリミット名を書く必要があります.CurrentTimeMillisは、その静的(static)メソッド、すなわち、このプロパティに値を割り当てるためにSystem.currentTimeMillis()メソッドを呼び出します.
3. :@Value("#{‘Spring EL付与文字列を使用"}")private String str=null;
4.科学計数法付与@Value("#{9.3 E 3}")private double d;
5.他のSpring Beanのプロパティを取得して、現在のBeanプロパティに@Value(#{beanName.str})private String otherBeanProp=nullを割り当てます.ここのbeanNameはSpring IoCコンテナBeanの名前です.strはその属性であり、対応するBeanを参照する属性を表して現在の属性に値を付与する
6.Spring ELによる計算#浮動小数点数比較演算@Value(#{beanName.pi==3.14 f}))private boolean piFlag;
#文字列比較演算@Value(#{beanName.str eq‘Spring Boot’}))private boolean strFlag;
#文字列接続@Value(#{beanName.str+'接続文字列’}))private String strApp=null;