Spring Series (iii) Advanced technology for Bean Assembly

Source: Internet
Author: User
Tags aliases
Profile

Unlike Maven profiles, spring's profile does not need to be repackaged, and the same version of the package file can be deployed on a server in a different environment, and it can only be switched to the corresponding environment by activating the corresponding source.

    • @Profile({"test","dev"})Java Config uses this annotation to specify which or which profile the bean belongs to. The parameter value is an array of strings for a profile. This annotation can be added to a class or method. The node corresponding to the XML Config is the attribute of the beans profile="dev" , which can be <beans> nested under the root node to define nodes belonging to different profiles, forming the following structure
<beans ...>    <beans profile="dev">        <bean ...>        <bean ...>    </beans>    <beans profile="prod">        <bean ...>    </beans>    ...</beans>
    • Through spring.profiles.active and spring.profiles.default can be set to activate which profile, if it is more than "," separate, spring preferred to use spring.profiles.active the settings, if not found, use spring.profiles.default the set value, if both are not set, Spring will assume that there is no profile to activate, it will only create those beans that are not added @Profile .

You can set these two properties in several ways:

    1. Initialization parameters of the Dispacherservlet
    2. Context parameters for Web apps
    3. Jndi
    4. Environment variables
    5. JVM System Properties
    6. Using annotations on test classes @ActiveProfiles

The following is the code in Web. XML that is set in the context and in the servlet spring.profiles.default

<web-app>    <!--上下文设置default profile-->    <context-param>        <param-name>spring.profiles.default</param-name>        <param-value>dev</param-value>    </context-param>    <servlet>        ...        <!--设置default profile-->        <init-param>            <param-name>spring.profiles.default</param-name>            <param-value>dev</param-value>        </init-param>    </servlet></web-app>
Conditionally-Typed beans

Spring4.0 introduces a conditional bean, which is created only if certain conditions are met. Profile is a conditional use, in fact, after the 4.0 version of the profile implementation mechanism and other conditional beans exactly the same, we can through the source of the profile of the condition of the bean mechanism.

@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Conditional(ProfileCondition.class) //注意这里, 条件化bean的注解public @interface Profile {    String[] value();}
    • @Conditional(ConditionClass.class)Java Config can add this annotation to the @Bean annotation method, the parameter value is a class type of variable, the class must implement the Condition interface, the method matchs() returns true to load the bean, otherwise ignored.

ConditionThe interface is defined as follows:

@FunctionalInterfacepublic interface Condition {    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata); }

ProfileConditionThe definition

class ProfileCondition implements Condition {    @Override    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {        // 获取profile注解的属性        MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());        if (attrs != null) {            // 获取value属性的值            for (Object value : attrs.get("value")) {                // 测试profile是否激活                if (context.getEnvironment().acceptsProfiles((String[]) value)) {                    return true;                }            }            return false;        }        return true;    }}
    • Through matchs() the two parameters of the method we can do (1) Get the information required by Conditioncontext to the context; (2) Get the annotations to the bean through Annotatedtypemetadata
Public interface Conditioncontext {//Gets the bean's registration information so that it can examine the bean definition beandefinitionregistry getregistry ();    Gets the Bean factory so that it can tell if the bean exists, gets other beans, and gets the state information of the Bean @Nullable configurablelistablebeanfactory getbeanfactory ();    Gets the environment variable, which is exactly the method of using this object Acceptsprofiles () checks whether the profile activates environment getenvironment ();    Gets the loaded resource Resourceloader getresourceloader (); Get ClassLoader @Nullable ClassLoader getclassloader ();}    Public interface Annotatedtypemetadata {//Check whether a comment is a Boolean isannotated (String annotationname);    The following methods can be used to obtain the bean's annotations, including its properties @Nullable map<string, object> getannotationattributes (String annotationname);    @Nullable map<string, object> getannotationattributes (String annotationname, Boolean classvaluesasstring);    @Nullable multivaluemap<string, object> getallannotationattributes (String annotationname); @Nullable multivaluemap<string, object> getallannotationattributes (String annotationname, Boolean classvaluesasstring);} 
Ambiguity of automatic assembly

Automatic assembly greatly simplifies the configuration of spring, for most application objects of the dependent bean, the implementation of the program generally has only one match, but there is also a match to multiple beans, spring does not handle this situation, it is necessary for developers to eliminate the ambiguity of the assembly.

    • @PrimaryAnnotations are used to specify that the bean being annotated is the preferred bean. However, if more than one matching bean is added, the annotation still does not disambiguate.
    • @QualifierAnnotations are used to qualify a bean's scope. With @AutoWired and in @Inject common use, the parameter value is used to specify Beanid, but using the default Beanid is unfriendly to refactoring @Component . @Bean when used with or together, the parameter value assigns an alias to the Bean, and the alias is typically a word description with a description of the bean feature. You can then use aliases when you inject them. But aliases may need to be defined multiple, qualifier does not support arrays, and does not allow multiple definitions (see below for reasons).
    • @QualifierRepeating tokens for the same bean is not allowed because the qualifier annotation definition does not add @Repeatable annotations.

You can use custom qualifying annotations to narrow the bean range.

The following code defines the bean using the qualifier method

@Component@Qualifier("cheap")public class QQCar implements Car{}@Component@Qualifier("fast")public class BenzCar implements Car{    }@Component@Qualifier("safe")//@Qualifier("comfortable") //行不通,不能加两个Qualifierpublic class BMWCar implements Car{    }

How to use custom qualifying annotations again

// 定义...@Qualifierpublic @interface Cheap{}...@Qualifierpublic @interface Fast{}...@Qualifierpublic @interface Safe{}...@Qualifierpublic @interface Comfortable{}// 使用@Component@Safe@Comfortablepublic class BMWCar implements Car{    }...

A custom-qualified method can be arbitrarily combined to qualify a bean's scope, because there is no string type, so it is type-safe.

Bean scope

Four types of scopes for beans:

    1. Singleton (Singleton) defaults to this scope, globally unique
    2. is created when the prototype (Prototype) is injected or retrieved from the context
    3. Session Web program is used, the same session remains unique
    4. Request Web program to use, each request unique
    • @ScopeJava Config uses this annotation to specify the scope of the bean, the parameter value is used to specify the scope, such as value=ConfigurableBeanFactory.SCOPE_PROTOTYPE the prototype and the singleton constants are defined in ConfigurableBeanFactory , the session and the requested constants are defined in, and the WebApplicationContext other parameter is proxyMode=ScopedProxyMode.INTERFACES used to specify how the proxy is created, The example specifies the use of an interface-based proxy method; If used proxyMode=ScopedProxyMode.TARGET_CLASS , the cglib is used to generate a class-based proxy.
      XML config corresponding to the properties of the bean, scope="prototype" for the web scope, you also need to specify the use of proxy, the sample code is as follows.
<bean id="beanid" class="..." scope="session">    <!--需要引用aop命名空间的.  proxy-target-class 默认为true, 使用CGLib创建代理, 指定为false则使用接口方式创建代理-->    <aop:scoped-proxy proxy-target-class="false"></bean>
    • Scope Why use proxy mode? If the bean is not singleton, Spring creates a proxy object for it, then injects the proxy object into it, and the actual bean is invoked by the proxy object delegate during the actual run. There are two advantages to this: (1) lazy loading, beans can be created when needed, and (2) Ease of scope extension
Property placeholders and Spel

Spring provides two ways to inject values at run time, thus avoiding the hard coding of literals into programs or configuration files.

    1. Property placeholder
    2. Spel

I. Property placeholders

Let's look at the following example:

@Configuration@PropertySource("classpath:/path/app.property")public class MyConfig{    @AutoWired    Environment env;    @Bean    public Car getCar(){        return new QQCar(env.getProperty("qqcar.price"));    }}
    • @PropertySource("classpath:/path/app.property")You can specify where to load the resource file, and with an instance of the environment class, ENV, you can get the nodes configured in the resource file. Environment Not only can you get the configured literal, it can also get a complex type and convert it to an instance of the corresponding class.<T> T getProperty(String key, Class<T> targetType);
    • XML Congif can use placeholders, as long as ${qqcar.price} they are configured under the context namespace to <context:property-placeholder /> generate a bean of type PropertySourcesPlaceholderConfigurer , which is used to resolve placeholders
    • If you turn on component scanning and automatic assembly, there is no need to specify a resource file or class to use @Value(qqcar.price) . Again, you need a PropertySourcesPlaceholderConfigurer bean of type.
@Beanpublic static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){    return new PropertySourcesPlaceholderConfigurer();}

Two. Spel with more powerful features

The characteristics of Spel are as follows:

    1. Using the Bean's ID to refer to the bean
    2. Calling methods and properties: You can invoke the bean's methods and properties through Beanid, just as you would in code.
    3. Arithmetic, logic, relational operations on values: Special note: the ^ exponentiation operator; ?: is an empty operator
    4. Regular expression matching: shaped like #{beanid.mobile matches ' 1 (?: 3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\ d|9\d) \d{8} '}
    5. Set operation: .?[] lookup operator; .^[] Find the first item to match; .$[] Find the last item to match; .![] A projection operator (such as getting an object in the set that meets the criteria, and taking one of the attributes into the result set);

Spel example #{1},#{t (System). Out.print ("test")},#{beanid.name},#{systemproperies["path"]}

Although Spel is powerful, we can write complex expressions through Spel, but overly complex expressions are not suitable for comprehension and reading, but they also increase the difficulty of testing. It is therefore recommended that you write concise expressions as much as possible.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.