Springアドバンスドアセンブリの条件化Beanの作成

7143 ワード

前節では、アプリケーションのパスの下に特定のライブラリが含まれている場合にのみ作成されるprofileメカニズムの条件付きBeanの作成の具体的な手順について説明しましたが、この項で説明するSpring 4および@Conditional注記を使用して条件付きBeanを定義するのは適切です.このレベルの条件付き構成を実現するのは容易ではありませんが、強力なSpring 4は@Conditional注記を提供しています.次に、@Conditionalを使用して条件付き構成Beanを実現する方法について説明します.次に、環境変数にmagic変数があるかどうかに基づいて、MagicBeanを作成するかどうかを決定します.
package com.cache.config;

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

import com.cache.conditional.MagicExistsConditional;
import com.cache.service.MagicBean;
/**
 * 
*
Description:study @Conditional
*
Company:
*
@date:2016 8 23 7:55:37
*
@author:Kong
*
*/ @Configuration public class ConditionalConfig { @Bean @Conditional(MagicExistsConditional.class) // bean public MagicBean magicBean() { return new MagicBean(); } }
MagicBeanが作成されるかどうかは、@Conditional(MagicExistsConditional.class)の場合によって異なります.では、@Conditionalのパラメータはどのようなタイプですか.
package com.cache.conditional;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
/**
 * 
*
Description: Bean
*
Company:
*
@date:2016 8 23 7:59:15
*
@author:Kong
*
*/ public class MagicExistsConditional implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Environment evn = context.getEnvironment(); return evn.containsProperty("magic"); } }

ご覧のように、@Conditionalに設定されたクラスは、Conditionインタフェースを任意に実装したタイプであってもよい.このインタフェースを実装するにはmatchesメソッドを実装する必要があり、matchesメソッドがtrueを返すとそのbeanを作成し、falseを返すとbeanを作成しない.上記の例では、環境変数にmagic変数があるかどうかに基づいてmatchesの戻り値を決定し、MagicBeanを作成するかどうかを決定した.上記の例では、ConditionContextからEnvironmentまで使用しただけですが、Conditionが実現する考慮要因はこれよりも多いかもしれません.maches()メソッドは、ConditionContextおよびAnnotatedTypeMetadataオブジェクトを決定するために得る.実はConditionContextはインタフェースです.
package org.springframework.context.annotation;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;

/**
 * Context information for use by {@link Condition}s.
 *
 * @author Phillip Webb
 * @since 4.0
 */
public interface ConditionContext {

    BeanDefinitionRegistry getRegistry();

    ConfigurableListableBeanFactory getBeanFactory();

    Environment getEnvironment();

    ResourceLoader getResourceLoader();

    ClassLoader getClassLoader();

}

ConditionContextでは、次のことができます.
方法
さぎょう
getRegistry()
返されたBeanDefinitionRegistryを使用してbeanの定義を確認します.
getBeanFactory()
返されたC o n f i g rableListableBeanFactoryを使用して、beanのプロパティを確認します.
getEnvironment()
環境変数が存在するかどうか、およびその値が何であるかを確認するには、環境変数を返します.
getResourceLoader()
戻ってきたResourceLoaderがロードしたリソースを読み取り、確認します.
getClassLoader()
戻ってきたClassLoaderによってクラスがロードされ、存在するかどうかを確認します.AnnotatedTypeMetadataでは、@Bean注記のある方法に他の注記があるかどうかを確認できます.
package org.springframework.core.type;

import java.util.Map;

import org.springframework.util.MultiValueMap;

/**
 * Defines access to the annotations of a specific type ({@link AnnotationMetadata class}
 * or {@link MethodMetadata method}), in a form that does not necessarily require the
 * class-loading.
 *
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @author Mark Pollack
 * @author Chris Beams
 * @author Phillip Webb
 * @since 4.0
 * @see AnnotationMetadata
 * @see MethodMetadata
 */
public interface AnnotatedTypeMetadata {

    boolean isAnnotated(String annotationType);

    Map getAnnotationAttributes(String annotationType);

    Map getAnnotationAttributes(String annotationType, boolean classValuesAsString);

    MultiValueMap getAllAnnotationAttributes(String annotationType);

    MultiValueMap getAllAnnotationAttributes(String annotationType, boolean classValuesAsString);

}

isAnnotated()メソッドを用いて,@Bean注釈付きメソッドに他の特定の注釈があるか否かを判断できる.他の方法では,@Bean注釈の方法における他の注釈の属性を調べることができる.次に、Spring 4の@Conditionalによる@Profileの再構築を見てみましょう.
package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.env.AbstractEnvironment;
import org.springframework.core.env.ConfigurableEnvironment;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {

    /**
     * The set of profiles for which the annotated component should be registered.
     */
    String[] value();

}
@Profileのインプリメンテーション定義は、@Conditional注記およびConditionインタフェースを使用し、以下のようにProfileConditionConditionをインプリメンテーションし、matchesメソッドにおいて@Profileを作成するか否かの決定を下した.

package org.springframework.context.annotation;

import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.MultiValueMap;

/**
 * {@link Condition} that matches based on the value of a {@link Profile @Profile}
 * annotation.
 *
 * @author Chris Beams
 * @author Phillip Webb
 * @author Juergen Hoeller
 * @since 4.0
 */
class ProfileCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        if (context.getEnvironment() != null) {
            MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
            if (attrs != null) {
                for (Object value : attrs.get("value")) {
                    if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
                        return true;
                    }
                }
                return false;
            }
        }
        return true;
    }

}

ProfileConditionは、AnnotatedTypeMetadataによって@Profile注釈に使用されるすべての属性を得ることができる.この情報を使用すると、beanのprofile名を含むvalueプロパティを明確にチェックします.次いで、ConditionContextによって得られたEnvironmen tに従って、「acceptsProfiles()法による」profileがアクティブであるかどうかを検査する.
続き、、、、