20191226 Spring official documents (Core 1.10)

1.10. Classpath scanning and managed components

1.10.1. @Component stereotype annotations and more

@RepositoryAnnotation is to achieve repository (also referred to as data access object or DAO) any type of marking or structural role. The use of the tag is automatically translated abnormal.

Spring provides further stereotype @Componentannotations: , @Serviceand @Controller. Any type of structure is a general @Component Spring managed components. @ Repository, @ Service and @Controller are more specialized for specific @Component use cases (respectively, persistence, service and presentation layer). Therefore, you can use @Component annotate your component classes, however, by @ Repository, @ Service or @Controller annotating them, your class better suited for treatment by a tool, or associating with aspects. For example, these stereotypes comment more suitable for an ideal entry point for the target. @ Repository, @ Service and @Controller in a future version of the Spring framework can also include other semantics. So, if you choose to use @Component or @ Service for service layer, @ Service it is clearly the better choice. Also, as previously, @ Repository numerals as already supported in a persistent abnormalities of automatic conversion layer.

Note composition may be selected from the metadata re-statement annotation properties to allow customization. When you want to open a subset of meta-annotation attributes, this feature is particularly useful. For example, Spring's @SessionScopeannotation scope name is hard-coded session, but still allow custom proxyMode.

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {

    /**
     * Alias for {@link Scope#proxyMode}.
     * <p>Defaults to {@link ScopedProxyMode#TARGET_CLASS}.
     */
    @AliasFor(annotation = Scope.class)
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

}

Then, you do not need to declare proxyModethe following can be used @SessionScope:

@Service
@SessionScope
public class SessionScopedService {
    // ...
}

You can also cover the value proxyMode, as shown in the following example:

@Service
@SessionScope(proxyMode = ScopedProxyMode.INTERFACES)
public class SessionScopedUserService implements UserService {
    // ...
}

1.10.3. Automatically detect and register the class definitions Bean

To automatically detect these classes and register the corresponding bean, you need to add @ComponentScanto the @Configurationclass, where the basePackagesproperty is the common parent package is scanned class. (Alternatively, you can specify a comma-separated, or separated by semicolons space-separated list, where each packet comprises a parent class.)

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
    // ...
}

For simplicity, the previous example may use the value property annotation (i.e., @ComponentScan("org.example")).

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="org.example"/>

</beans>

Use <context:component-scan>implicitly enabled <context:annotation-config>features. <context:annotation-config>When using normally need not contain <context:component-scan>elements.

In addition, when you use the component-scan element, AutowiredAnnotationBeanPostProcessorand CommonAnnotationBeanPostProcessorimplicitly included. This means that these two components will automatically detect and assemble them, and all this does not need to provide any bean XML configuration metadata.

You can disable registration AutowiredAnnotationBeanPostProcessorand CommonAnnotationBeanPostProcessor, by setting the annotation-configproperty value false.

1.10.4. Use custom scan filter

By default, the type of annotations @ Component, @ Repository, @ Service , @ Controller, @Configuration, or self-defined annotation itself with @Component is the only component of the detected candidate. However, you can customize filters to modify and extend this behavior by the application. They add @ComponentScanto includeFiltersor excludeFiltersattribute (or XML configuration <context:component-scan>element <context:include-filter />or <context:exclude-filter />sub-element). Each filter element needs typeand expressionproperties. The following table describes the filtering options (range type attributes):
filter type | Examples | Description
--- | --- | ---
Annotation (default) | org.example.SomeAnnotation | type level in the target assembly the presence or the presence of yuan notes.
assignable | org.example.SomeClass | target component can be assigned to (or extended implementation) class (or interface).
AspectJ | org.example .. Service + | target component to match AspectJ type expressions.
regex | org.example.Default.
| to match the class name of the target component regular expressions.
custom | org.example.MyTypeFilter | org.springframework.core.type.TypeFilter custom interface implementation.

@Configuration
@ComponentScan(basePackages = "org.example",
        includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
        excludeFilters = @Filter(Repository.class))
public class AppConfig {
    ...
}


<beans>
    <context:component-scan base-package="org.example">
        <context:include-filter type="regex"
                expression=".*Stub.*Repository"/>
        <context:exclude-filter type="annotation"
                expression="org.springframework.stereotype.Repository"/>
    </context:component-scan>
</beans>

You can also set annotations useDefaultFilters=falseby providing labels or use-default-filters="false"to disable the default filter properties. This effectively disables the use of @Component, @Repository, @Service, @Controller, @RestController, or @Configurationautomatic detection element annotation annotate or class.

1.10.5. Bean definitions metadata component

@Component
public class FactoryMethodComponent {

    @Bean
    @Qualifier("public")
    public TestBean publicInstance() {
        return new TestBean("publicInstance");
    }

    public void doWork() {
        // Component method implementation omitted
    }
}

@BeanNote plant identification methods, and other characteristics bean definition, with a value defined as @Qualifierannotated. Other methods that can be specified level annotations are @Scope, @Lazyand define custom annotations.

In addition to the role of the external component initialization, you can also @Lazy marked with comments placed in @Autowiredor @Injecton the point of injection. In this case, it leads into a delay resolution agent.

As described above, the automatic assembly supporting fields and methods, and automatically supports additional support @Bean method. The following example shows how to do this:

@Component
public class FactoryMethodComponent {

    private static int i;

    @Bean
    @Qualifier("public")
    public TestBean publicInstance() {
        return new TestBean("publicInstance");
    }

    // use of a custom qualifier and autowiring of method parameters
    @Bean
    protected TestBean protectedInstance(
            @Qualifier("public") TestBean spouse,
            @Value("#{privateInstance.age}") String country) {
        TestBean tb = new TestBean("protectedInstance", 1);
        tb.setSpouse(spouse);
        tb.setCountry(country);
        return tb;
    }

    @Bean
    private TestBean privateInstance() {
        return new TestBean("privateInstance", i++);
    }

    @Bean
    @RequestScope
    public TestBean requestScopedInstance() {
        return new TestBean("requestScopedInstance", 3);
    }
}

From the beginning of Spring Framework 4.3, you can also declare InjectionPointtype (or more specific sub-categories: DependencyDescriptor) factory method parameters to request access trigger point injection current bean created. Note that this only applies to the actual creation of the Bean instance, does not apply to inject an existing instance. Therefore, this feature makes the most sense for the bean prototype range. For other scopes, Factory methods given only see scope bean instance trigger to create a new injection point (e.g., trigger the creation of a single embodiment bean inert dependency). In this case, the injection point may be provided with semantics using metadata. The following example shows how to use InjectionPoint:

@Component
public class FactoryMethodComponent {

    @Bean @Scope("prototype")
    public TestBean prototypeInstance(InjectionPoint injectionPoint) {
        return new TestBean("prototypeInstance for " + injectionPoint.getMember());
    }
}

@Bean @Configuration different handling peer mode in the conventional method Spring assembly in Spring. The difference is that, CGLIB not enhance @Component class to intercept calls to methods and fields. CGLIB proxy is a way to call @Configuration class method or methods @Bean fields by this method to create Bean metadata references to collaborating objects. Such methods than using plain Java call semantics, but rather through the container to provide a normal life-cycle management and Spring Bean agents, even when referenced by other program calls @Bean Bean method. In contrast, a standard Java semantics call fields @Bean method or @Component class is in the general area, no special handling or other restrictions CGLIB.

You can @Bean methods declared static, without allowing them to create calls for the case of the example configuration classes it contains. After defining the processor Bean (e.g. BeanFactoryPostProcessoror BeanPostProcessortime type), which is particularly interesting since such Bean initialized early in the life cycle of the container, and other parts should be avoided at the time of the trigger configuration.

Due to technical limitations, the method calls to static @Bean never be blocked vessel, even if the class is not @Configuration (as described earlier in this section), because of technical limitations: CGLIB subclass cover only non-static method. As a result, a direct call to another Java method @Bean with semantic criteria, resulting in a separate instance returned from the factory method itself.

@Bean method of visibility of the Java language does not have a direct impact on the results of the Spring container bean definitions. You are free to declare their factory method to fit a non-@Configuration class, static methods can also be used in any place. However, the conventional method @Bean @ Configuration class must be rewritten, that is to say, may not be declared as privateor final.

The method can also be found in the base class @Bean given component type or configuration and the Java 8 default method declared in an interface implemented by a component or class configuration. This provides great flexibility for a combination of complex configuration arrangements, starting with Spring 4.2, or even multiple inheritance can be the default method by Java 8.

Finally, a single class can keep multiple @Bean same method of a bean, depending on the dependency is available at run time, to arrange a plurality of factory methods. This is the same as selecting the "most greedy" constructor or factory method embodiment in other configurations algorithm: when a selected configuration having a maximum number of variants have dependencies between a plurality of similar containers @Autowired constructors conduct of selection.

1.10.6. Automatic detection named component

When the assembly is automatically detected as part of the scanning process, which is known by the scanner name bean BeanNameGeneratorpolicy generation. By default, any Spring stereotype annotations (@ Component, @ Repository, @ Service and @Controller), which contains a name value, thereby providing the name of the corresponding bean definition.

If this value does not include annotations value, or does not contain any other components detected (e.g., by a component found in custom filters), the default bean name generator will return a non-qualified class name does not use capital letters. For example, if it is detected the component class, and the name is myMovieLister movieFinderImpl:

@Service("myMovieLister")
public class SimpleMovieLister {
    // ...
}
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}

If you do not want to rely on the default naming strategy Bean, Bean, you can provide a custom naming policy. First of all, realize BeanNameGenerator interfaces, and be sure to include a default no-arg constructor. Then, the fully qualified class name provided when configuring the scanner, as the following example Bean definitions and comments:

@Configuration
@ComponentScan(basePackages = "org.example", nameGenerator = MyNameGenerator.class)
public class AppConfig {
    // ...
}


<beans>
    <context:component-scan base-package="org.example"
        name-generator="org.example.MyNameGenerator" />
</beans>

As a general rule, whenever the other components may be explicitly referenced, consider using annotations to specify the name. On the other hand, as long as the container is responsible for loading, auto-generated name is sufficient.

1.10.7. To provide automatic detection component scoped

@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
    // ...
}

@ScopeNote only introspection In particular the bean class (for annotated components) or factory methods (Method for @Bean). In contrast to XML bean definition, there is no definition of the concept of inheritance bean, and is independent of the class-level inheritance hierarchy and metadata purpose.

To provide custom strategies for range resolution, rather than relying on the annotation-based method can achieve ScopeMetadataResolverthe interface. Be sure to include a default no-argument constructor. Then, it is possible to provide a fully qualified class name when configuring the scanner, as defined in the following notes and Bean example:

@Configuration
@ComponentScan(basePackages = "org.example", scopeResolver = MyScopeResolver.class)
public class AppConfig {
    // ...
}

<beans>
    <context:component-scan base-package="org.example" scope-resolver="org.example.MyScopeResolver"/>
</beans>

With some non-single scope, it may be necessary to generate the proxy for the scope object. To this end, component-scanthe elements can use scoped-proxyattributes. The three possible values noare: , interfaces, and targetClass. For example, the following configuration generates a dynamic proxy standard JDK:

@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
    // ...
}

<beans>
    <context:component-scan base-package="org.example" scoped-proxy="interfaces"/>
</beans>

1.10.8. Providing qualifier metadata annotated

reference

@Component
@Qualifier("Action")
public class ActionMovieCatalog implements MovieCatalog {
    // ...
}
@Component
@Genre("Action")
public class ActionMovieCatalog implements MovieCatalog {
    // ...
}
@Component
@Offline
public class CachingMovieCatalog implements MovieCatalog {
    // ...
}

And most annotated based on the same alternative, remember, binding annotation metadata to the class definition itself, and the use of XML allows the same type of bean to provide a plurality of variants thereof qualifier metadata, because metadata is press instance rather than by class.

1.10.9. Generating an index candidate components

Although the class path scanning is very fast, but you can start to improve the performance of large applications by creating a static list of candidates at compile time. In this mode, all of the modules as a component of a scanning target must use this mechanism.

Your existing @ComponentScanor <context:component-scan>command must remain intact to some candidate scan request context package. When detecting such ApplicationContext index, it will automatically use it instead of the scan path type.

To generate the index, each module requested to add additional components comprising dependencies, these components are the target component scan instruction. The following example shows how to operate Maven:

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-indexer</artifactId>
        <version>5.2.1.RELEASE</version>
        <optional>true</optional>
    </dependency>
</dependencies>

For Gradle 4.5 and earlier versions, it should be declared dependencies compileOnly configuration, as shown in the following example:

dependencies {
    compileOnly "org.springframework:spring-context-indexer:5.2.1.RELEASE"
}

For Gradle 4.6 and later, configuration shall annotationProcessor declared dependencies, as shown in the following example:

dependencies {
    annotationProcessor "org.springframework:spring-context-indexer:{spring-version}"
}

This procedure generates a file contained in the jar META-INF/spring.componentsfiles.

When using this mode in the IDE, it must spring-context-indexerbe registered as an annotation processor to ensure that the index when updating candidate components are up to date.

Found on the class path META-INF/spring.components, the index is automatically enabled. If an index for some libraries (or use cases) partially available, but you can not build an entire application, you can be spring.index.ignoreas setting trueretreated to the classpath arrange conventional (as if there is no index) back and forth, it can be set to the system attribute may be set as the path to the root of the class spring.propertiesfile.

Guess you like

Origin www.cnblogs.com/huangwenjie/p/12104016.html