In those years we were fascinated by Spring: bean annotation implementation (6)

Spring-bean definition and scope annotation implementation

1. Classpath scanning and component management

After 3.0, define beans through java annotations instead of xml, such as:
@configuration @Bean @Import @DependsOn

  • @Component is a general annotation, which can be used for any bean
  • @Respority usually annotates the DAO class, which is the persistence layer
  • @Service is usually used to annotate the Service class, which is the service layer
  • @Controller is usually used in the Controller class, which is the control layer (mvc)

2. Meta annotations

1. Many annotations provided by Spring can be used as their own code, that is, "metadata annotations". Meta annotation is a simple annotation that can be applied to another annotation
2. In addition to value(), meta annotations can also have other attributes, allowing Customized

Four yuan annotations are: @ Target, @ Retention, @ Documented, @ Inherited, is designed to define the annotation annotations , which effect are as follows:
@Target for annotation indicates that what where possible enumeration class values ElemenetType includes:

ElemenetType Description
ElemenetType.CONSTRUCTOR Constructor declaration
ElemenetType.FIELD Domain declaration (including enum instance)
ElemenetType.LOCAL_VARIABLE Local variable declaration
ElemenetType.METHOD Method declaration
ElemenetType.PACKAGE Package declaration
ElemenetType.PARAMETER Parameter declaration
ElemenetType.TYPE Class, interface (including annotation type) or enum declaration

@Retention indicates at what level the annotation information is saved.
Optional parameter values ​​are in the enumeration type RetentionPolicy, including:

RetentionPolicy Description
RetentionPolicy.SOURCE Annotations will be discarded by the compiler
RetentionPolicy.CLASS Annotations are available in the class file, but will be discarded by the VM
RetentionPolicy.RUNTIME VM The annotation will also be kept at runtime, so the annotation information can be read through the reflection mechanism.

@Documented includes this annotation in javadoc, which means that this annotation will be extracted into a document by the javadoc tool.
The content in the doc document will be different due to the different information content of this annotation. Quite similar to @see, @param, etc.
@Inherited allows subclasses to inherit the annotations in the parent class.

3. Automatic detection of classes and bean registration

Spring can automatically detect the class and register the bean to the ApplicationContext. The
class is annotated with @Service@Controller and other annotations.

<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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd>
<!-- <context:component-scan>可以实现基于类的注解,
而<context:annotation-config>只能在完成了bean的注册配置之后实现对成员变量和方法的注解,
前者包含后者,一般配置了前者之后就不再配置后者了。
AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor也会被包含 -->
	<context:component-scan base-package:"org.example"/>
<beans>

4. Use filters for custom scans

By default, the condition for the class to be automatically discovered and bean registered is: use @component @repository @service @controller or use @Component custom annotation

The above behavior can be modified through the filter, the following xml configuration, ignore all @resporitory annotations ( context:exclude-filter) and replace it with stub

<beans>
	<context:component-scan base-package:"org.example">
	<!--包含过滤器 -->
	<context:include-filter type="regex"--通配符
	expression=".Stub.*Respository"/>
	<!--排除过滤器 -->
	<context:exclude-filter type="annotation"
	expression="org.springframework.stereotype.Respository"/>
	</context:component-scan>
<beans>

You can also use to user-default-filter:falsedisable automatic discovery and registration

5. Define the bean

Define bean

6. Scope

Scope

7.spring proxy mode

The scoped-proxy attribute specifies the proxy, there are three values ​​to choose from: no (default) interface, target-class

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

1.Required

The @Required annotation applies to the setter method of
the bean property. This annotation only means that the affected bean property must be filled (assigned) during configuration, through a clear property value in the bean definition or through automatic assembly

public class SimpleMovieLister{
    
    
	private MovieFinder  movieFinder;	
	@Required
	public void setMovieFinder(MovieFinder movieFinder){
    
    
		this.movieFinder=movieFinder;
	}
}

2.AutoWired

@AutoWired can be annotated as a "traditional" setter method

private MovieFinder  movieFinder;	
@AutoWired
public void setMovieFinder(MovieFinder movieFinder){
    
    
		this.movieFinder=movieFinder;
	}

Can also be used on constructors or member variables

@AutoWired
private MovieFinder  movieFinder;	

private Customer**Dao  customer**Dao;
@AutoWired
public  ***(Customer**Dao  customer**Dao){
    
    
		this.customer**Dao=customer**Dao;
	}

By default, if autowiring fails and an exception is thrown because it cannot find a suitable bean , you can set the required attribute to false on the annotation

@AutoWired(required=false)
public void setXX(XX xx){
    
    
    this.xx = xx
}

Each class can only have one constructor marked as required=true {There can be multiple constructors under each class}
The necessary attributes of AutoWired, it is recommended to use @Required annotation (in the above case, use Required instead of AutoWired. Generally use AutoWired)

3. The difference between @AutoWired and @Resource annotations

  • Spring not only supports the @Autowired annotation defined by itself, but also supports several annotations defined by the JSR-250 specification. They are@Resource、@PostConstruct以及@PreDestroy。
  • The role of @Resource is equivalent to @Autowired, except that it is @Autowired按byType(即class)automatically injected, but @Resource默认按byName(即ID)自dynamic injection.
  • @Resource has two attributes that are more important name和type. Spring parses the name attribute annotated with @Resource as the name of the bean, while the type attribute parses as the type of the bean.

So if the name attribute is used, the automatic injection strategy of byName is used, and the automatic injection strategy of byType is used when the type attribute is used. If neither the name nor the type attribute is specified, then the byName automatic injection strategy will be used through the reflection mechanism .

@Resource assembly order

If specified at the same time name和type, the only matching bean is found from the Spring context for assembly, and an exception is thrown
if it is not found. If specified name, the bean with a matching name (id) is found from the context for assembly, and if it is not found, an exception is thrown. Exception
If specified type, the only bean with a matching type is found in the context for assembly.
If 既没有指定name,又没有指定typeit is not found or if more than one bean is found, an exception will be thrown. If it is automatically assembled according to the byName method; if there is no match, it will fall back to an original Match the type, and automatically assemble if it matches;

The difference between @Autowired and @Resource:

  1. Both @Autowired and @Resource can be used to assemble beans. Both can be written on the field or on the setter method
  2. @Autowired is 类型assembled by default (this annotation belongs to spring). By default, the dependent object must exist. If you want to allow null values, you can set its required attribute to false, such as:, @Autowired(required=false)if we want to use name assembly, we can combine @Qualifier annotation for use
  3. @Resource (this annotation belongs to J2EE), the default 名称is assembled according to the name, the name can be specified by the name attribute, if the name attribute is not specified, when the annotation is written on the field, the field name is used by default to search, if the annotation is written in the setter method By default, the attribute name is used for assembly. When no bean matching the name is found, the assembly is performed according to the type. But it should be noted that if the name attribute is specified, it will only be assembled according to the name.
  4. The difference
    in the scope of use @AutoWired applies to fields, constructors, multi-argument, methods, which allow @Qualifier annotations to be used at the parameter level to narrow the scope
    @Resource applies to member variables, only one parameter setter method , so the target is the constructor Or a multi-parameter method, the best way is to use qualifiers

Recommended use: @Resource annotation is on the field, so there is no need to write a setter method, and this annotation belongs to J2EE, which reduces the coupling with spring. This code looks more elegant.

4. Other uses

You can use @Autowired to annotate those well-known resolution dependency interfaces, such as: BeanFactory, ApplicationContext , Environment, ResourceLoader, ApplicationEventPublisher, MessageSource;

Write picture description here
But Order is only valid for arrays ,对map集合无效

BeanOneImpl and BeanTwoImpl both implement BeanInterface

 @Autowired
 private List<BeanInterface> list;
//遍历list
 for (BeanInterface bean : list) {
    
    
     System.out.println(bean.getClass().getName());
}
//输出
com.zjx.multibean.BeanTwoImpl
com.zjx.multibean.BeanOneImpl

@Autowired
private Map<String, BeanInterface> map;
//遍历map
 for (Map.Entry<String, BeanInterface> entry : map.entrySet()) {
    
    
       System.out.println(entry.getKey() + "   "
                  + entry.getValue().getClass().getName());
	}
//输出
beanOneImpl   com.zjx.multibean.BeanOneImpl
beanTwoImpl   com.zjx.multibean.BeanTwoImpl

5. Attention

@Autowired is processed by Spring BeanPostProcessor, so you cannot apply these annotations to your own BeanPostProcessor or BeanFactoryPostProcessor types. These types must be loaded through XML or Spring @Bean annotations

@Qualifier

By type of automatic assembly may have multiple instances of bean may be used in the Spring @Qualifierannotation narrow range (or specified unique), may also be used to specify a separate configuration parameters, or process parameters

// 在BeanInvoker类中增加一个成员变量,因为我们不知道BeanInterface的实现类是哪一个
 //(beanOneImpl、beanTwoImpl),通过@Qualifier注解缩小范围为id为”beanTwoImpl”的这个实现类
	@Autowired
    @Qualifier("beanTwoImpl")
    private BeanInterface beanInterface;

@Autowired
private void setComedyCatalog(@Qualifier("对应id") MovieCatalog comedyCatalog){
    
    
    this.comedyCatalog = comedyCatalog;
}

Can be used to annotate collection type variables

If annotation injection is performed by name , it is mainly not @Autowired (even if it is technically possible to specify the name of the bean through @Qualifier), the alternative is to use JSR-250@Resource annotations to identify specific targets through its unique name (This is a matching process that has nothing to do with the declared type)

Use @Resource annotation to refer to collection or Map bean by unique name

Spring uses @Autowired to inject the map into the problem.
When we use Autowired to inject a map or other collection type, spring does not take the bean according to the beanName and assign it, but takes out all the matching beans from the container at one time according to the set type and puts them directly into it. To the collection.
[Spring] @Autowired In-Depth Anatomy of Collection Types of Injection Classes

Guess you like

Origin blog.csdn.net/eluanshi12/article/details/86477908