Spring annotation @Component, @Repository, @Service, @Controller difference

In addition to providing @Component annotations in spring 2.5, several annotations with special semantics are also defined, they are: @Repository, @Service and @Controller. In the current Spring version, these three annotations are equivalent to @Component, but from the naming of the annotation classes, it is easy to see that these three annotations are related to the persistence layer, business layer and control layer (Web layer). correspond. Although these three annotations are nothing new compared to @Component, Spring will add special functionality to them in future releases. Therefore, if the Web application adopts the classic three-tier hierarchical structure, it is better to annotate the classes in the hierarchy with @Repository, @Service and @Controller respectively in the persistence layer, business layer and control layer, and use @ Component annotates the more neutral classes.

In a slightly larger project, there are usually hundreds of components. If these components are configured with xml bean definitions, it will obviously increase the size of the configuration file, and it is not very convenient to find and maintain. Spring 2.5 introduces an automatic component scanning mechanism for us. He can search for classes annotated with @Component, @Service, @Controller, @Repository annotations under the classpath, and incorporate these classes into the spring container for management. It works the same as configuring the component using the bean node in the xml file. To use the automatic scanning mechanism, we need to open the following configuration information:
<context:component-scan base-package=”com.eric.spring”>

Where base-package is the package to be scanned (including all sub-packages) @Service is used to label business layer components, @Controller is used to label control layer components (such as action in struts), and @Repository is used to label data access components, ie DAO components, and @Component refers to components in general. When components are not well classified, we can use this annotation to mark them. When using the member variables of these component annotation classes for injection, there is no need to generate set and get methods, and spring will inject them automatically.

By default, the classes marked with these annotations are singletons. If you want to customize them, you can use @Service("beanName")@Scope("prototype") to change them. In addition, you can also customize the specified initialization method and destruction method (the method name is arbitrary):
@PostConstruct
public void init() {
}
@PreDestroy
public void destory() {
}


In the spring configuration file, you only need to add
<context:annotation-config/>

and
<context:component-scanbase-package="The package where the class that needs to be injected is located"/>
, you can use base-package="*" to indicate all classes.
<context:component-scan base-package=”com.eric.spring”>

The base-package is the package that needs to be scanned (including all subpackages)


. The @Autowired and @Qualifier annotations are marked in front of the interface so that the interface can be injected by the container. When there are two implementation classes for the interface, one must be specified for injection. Use Implement the class with a lowercase string to inject, such as:
@Autowired
@Qualifier("chinese")       
private Man man;

Otherwise it can be omitted and just write @Autowired.

@Service service layer component is used to mark business layer components, which means to define a bean, and automatically instantiate a bean with a lowercase letter according to the class name of the bean. For example, Chinese is instantiated as Chinese. If you need to change the name yourself: @ Service("The bean name you changed by yourself").


The following mainly explains the difference between the @Autowired annotation and @Resource annotation in Spring:
Spring not only supports the @Autowired annotation defined by itself, but also supports several annotations defined by the JSR-250 specification, which are @Resource, @PostConstruct and @PreDestroy.
The role of @Resource is equivalent to @Autowired, except that @Autowired is automatically injected according to byType, while @Resource is automatically injected according to byName by default. @Resource has two important attributes, namely name and type. Spring parses the name attribute of the @Resource annotation as the name of the bean, and the type attribute parses it 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, the strategy will be automatically injected using byName through the reflection mechanism.

The Resource annotation class is located in the lib/j2ee/common-annotations.jar class package of the Spring distribution, so it must be added to the project's class library before it can be used.

@Resource assembly order:
1. If both name and type are specified, find the only matching bean from the Spring context for assembly, and throw an exception if not found
2. If name is specified, the bean with the matching name (id) will be found from the context for assembly, and an exception will be thrown if it is not found
. 3. If type is specified, the only bean with matching type will be found from the context for assembly, and an exception will be thrown. If it is not found or if more than one is found, an exception will be thrown
. 4. If neither name nor type is specified, it will be assembled automatically according to the byName method; if there is no match, it will fall back to a primitive type to match, if it matches, it will be automatically Assembly;

The difference between @Autowired and @Resource:
1. Both @Autowired and @Resource can be used to assemble beans. Both can be written on fields or setter methods.
2. @Autowired is assembled by type 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 property to false, such as: @Autowired(required= false), if we want to use name assembly, we can use it in conjunction with the @Qualifier annotation.
3. @Resource (this annotation belongs to J2EE), the default installation name is used for assembly, and the name can be specified through the name attribute. If the name attribute is not specified, when the annotation is written on the field, the field name is used for installation name lookup by default. If The annotation is written on the setter method by default with the property name for assembly. Assemble by type when no bean matching the name is found. But it should be noted that if the name attribute is specified, it will only be assembled according to the name.
Recommended use: @Resource is annotated on the field, so that there is no need to write a setter method, and this annotation belongs to J2EE, reducing the coupling with spring. This way the code looks more elegant.

In general, we don't need to use annotations like @Resource(type=Car.class) because the Bean's type information can be obtained from the code through Java reflection. 


Compared with XML configuration, annotation configuration has many advantages: 
1. It can make full use of Java's reflection mechanism to obtain class structure information, which can effectively reduce configuration work. For example, when using JPA annotations to configure ORM mapping, we do not need to specify the PO's attribute name, type and other information. If the relationship table fields and PO attribute names and types are the same, you don't even need to write task attribute mapping information - because these information are all It can be obtained through the Java reflection mechanism.  
2. Comments and Java code are located in one file, while XML configuration uses a separate configuration file. Most of the configuration information will not be adjusted after the program is developed. If the configuration information and Java code are put together, it will help to enhance the program's Cohesion. With an independent XML configuration file, programmers often need to keep switching between program files and configuration files when writing a function. This kind of incoherence in thinking will reduce development efficiency.  
3. Therefore, in many cases, annotation configuration is more popular than XML configuration, and annotation configuration has a trend of further popularity. One of the big enhancements in Spring 2.5 is the introduction of many annotation classes, and now you can use annotation configuration to do most of the functionality of XML configuration.

Spring 2.5 introduced the @Autowired annotation, which can annotate class member variables, methods and constructors to complete the automatic wiring. Let's take a look at the code for automatic injection of member variables using @Autowired:
...... Code omitted......
Spring resolves @Autowired through a BeanPostProcessor, so to make @Autowired work, you must declare the AutowiredAnnotationBeanPostProcessor Bean in the Spring container in advance. 
<!-- The BeanPostProcessor will work automatically and automatically inject beans marked with @Autowired -->  
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

In this way, when the Spring container starts, the AutowiredAnnotationBeanPostProcessor will scan all the beans in the Spring container. When it finds that the bean has the @Autowired annotation, it will find the bean that matches it (matching by type by default) and inject it into the corresponding place.

The article also mentioned: To
make the JSR-250 annotations effective, in addition to annotating these annotations in the Bean class, you also need to register a BeanPostProcessor responsible for processing these annotations in the Spring container:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>

CommonAnnotationBeanPostProcessor implements the BeanPostProcessor interface, which is responsible for scanning beans annotated with JSR-250 and performing corresponding operations on them.

Another point I don't understand: What is the difference between AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor? ? ?


Of course, you can also annotate methods or constructors with @Autowired, see the following code:
package com.baobaotao;  
public class Boss {  
private Car car;  
private Office office;  
@Autowired  
public void setCar(Car car) {
		this.car = car;  
}
@Autowired
public void setOffice(Office office) {  
		this.office = office;  
}
}

At this time, @Autowired will find the beans of the parameter type of the marked method, and call the method to automatically inject these beans. The following usage method annotates the constructor:
package com.baobaotao;  
public class Boss {  
private Car car;  
private Office office;  
@Autowired  
public Boss(Car car ,Office office){  
		this.car = car;  
		this.office = office ;  
}  
}

Since the Boss() constructor has two parameters, car and office, @Autowired will look for beans that match their types, and use them as the parameters of Boss (Car car , Office office) to create a Boss Bean. 

When using the @Autowired annotation for auto-injection by default, the number of matching candidate beans in the Spring container must be one and only one. When a matching bean cannot be found, the Spring container will throw a BeanCreationException and indicate that there must be at least one matching bean.
When it is not certain that the Spring container must have a bean of a certain class, you can use @Autowired(required = false) where the bean of this class needs to be automatically injected, which is equivalent to telling Spring that an error will not be reported when no matching bean is found. .
Of course, under normal circumstances, the use of @Autowired requires Bean injection. The use of automatic injection and allowing no injection is generally only encountered during the development or testing period (for example, in order to quickly start the Spring container, only the introduction of Spring configuration files for some modules), so @Autowired(required = false) is rarely used.
An error opposite to not finding a type matching bean is that if the Spring container has more than one candidate bean, the Spring container will also throw a BeanCreationException at startup.
Spring allows us to specify the name of the injected bean through the @Qualifier annotation, so the ambiguity is eliminated, and the exception can be resolved by the following methods: 
@Autowired  
public void setOffice(@Qualifier("office")Office office) {  
		this.office = office;  
}

Use the @Qualifier annotation to specify the name of the injected bean.

The office in @Qualifier("office") is the name of the bean, so when @Autowired and @Qualifier are used in combination, the auto-injection strategy is changed from byType to byName. @Autowired can annotate member variables, methods, and constructors, while @Qualifier's annotation objects are member variables, method parameters, and constructor parameters. It is because of the difference of annotation objects that Spring does not unify @Autowired and @Qualifier into one annotation class. Here is the code to annotate member variables and constructor arguments: Annotate
member variables:
public class Boss {
@Autowired  
private Car car;       
@Autowired  
@Qualifier("office")  
private Office office;  
}

Annotate the constructor parameters: 
public class Boss {  
private Car car;  
private Office office;  
@Autowired  
public Boss(Car car , @Qualifier("office")Office office){  
		this.car = car;  
		this.office = office ;  
}
}


@Qualifier can only be used in conjunction with @Autowired and is a useful complement to @Autowired. In general, @Qualifier annotating parameters in method signatures will reduce the readability of the code, while annotations on member variables are relatively better. 

Beans in the Spring container have a life cycle. Spring allows specific operations to be performed after the bean is initialized and before the bean is destroyed. You can customize the operation methods after initialization/before destruction by implementing the InitializingBean/DisposableBean interface, or you can The action method to be invoked after initialization/before destruction is specified via the init-method/destroy-method attribute of the <bean> element. Regarding Spring's life cycle, the author has described it in detail in Chapter 3 of "Mastering Spring 2.x - Enterprise Application Development", and interested readers can refer to it. 

JSR-250 defines two annotation classes for the specification of methods after initialization/before destruction, namely @PostConstruct and @PreDestroy, these two annotations can only be applied to methods. Methods annotated with the @PostConstruct annotation will be called after the class is instantiated, and methods annotated with @PreDestroy will be called before the class is destroyed.

We know that no matter whether it is configured by implementing the InitializingBean/DisposableBean interface or through the init-method/destroy-method attribute of the <bean> element, only one initialization/destroy method can be specified for a bean. But using @PostConstruct and @PreDestroy annotations can specify multiple initialization/destruction methods, those methods annotated with @PostConstruct or @PreDestroy will be executed during initialization/destruction.


Simplified configuration with <context:annotation-config/>:
Spring 2.1 adds a new context Schema namespace that provides convenient configuration for annotation-driven, properties file import, load-time weaving, and more. We know that the annotation itself doesn't do anything, it only provides metadata information. For metadata information to really work, the processors responsible for handling that metadata must work.
The AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor we introduced earlier are the processors that process these annotation metadata. But defining these beans directly in the Spring configuration file is clumsy. Spring provides us with a convenient way to register these BeanPostProcessors, which is <context:annotation-config/>. Please see the configuration below:
<?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   
   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
   http://www.springframework.org/schema/context   
   http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
      <context:annotation-config/>   
      <bean id="boss" class="com.baobaotao.Boss"/>  
      <bean id="office" class="com.baobaotao.Office">  
          <property name="officeNo" value="001"/>  
      </bean>  
      <bean id="car" class="com.baobaotao.Car" scope="singleton">  
          <property name="brand" value=" 红旗 CA72"/>  
          <property name="price" value="2000"/>  
      </bean>  
</beans>

<context:annotation-config/> will implicitly register the four BeanPostProcessors AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor and requiredAnnotationBeanPostProcessor with the Spring container. 
Before using the context namespace in a configuration file, the context namespace must be declared in the <beans> element.

@Component has an optional input parameter to specify the name of the bean. In Boss, we define the bean name as "boss". In general, beans are singletons, and the place where beans need to be injected only need to be injected automatically through the byType strategy, so there is no need to specify the name of the bean. 
After annotating with @Component, the Spring container must enable the class scanning mechanism to enable annotation-driven bean definition and annotation-driven bean auto-injection strategies. Spring 2.5 extends the context namespace to provide this functionality, see the following configuration: 
<?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   
   http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
   http://www.springframework.org/schema/context   
   http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
      <context:component-scan base-package="com.baobaotao"/>  
</beans>

Here, all configuration content that defines beans through the <bean> element has been removed, and only one line of <context:component-scan/> configuration needs to be added to solve all problems - the Spring XML configuration file has been extremely simplified (of course the configuration Metadata is still needed, just in the form of comments). The base-package attribute of <context:component-scan/> specifies the class package to be scanned. All classes in the class package and its recursive subpackages will be processed.


It is worth noting that the <context:component-scan/> configuration item not only enables the scanning of class packages to implement annotation-driven bean definitions, but also enables annotation-driven automatic injection (that is, it is also implicitly registered internally AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor), so when <context:component-scan/> is used, <context:annotation-config/> can be removed. 
By default, the beans defined by @Component are singleton. If you need to use beans with other scopes, you can achieve the goal through the @Scope annotation.

The application of annotation configuration and XML configuration:
whether there are these IOC annotations, we will Can you completely get rid of the original XML configuration? the answer is negative. There are several reasons:
1. Annotation configuration is not necessarily inherently better than XML configuration. If the dependency of the bean is fixed (such as which DAO classes the Service uses), and this configuration information will not be adjusted during deployment, then the annotation configuration is better than the XML configuration; otherwise, if the dependency will be deployed during deployment XML configuration is obviously better than annotation configuration, because annotations are adjustments to the Java source code, and you need to rewrite the source code and recompile to implement the adjustment.
2. If the Bean is not a class written by itself (such as JdbcTemplate, SessionFactoryBean, etc.), the annotation configuration will not be implemented. At this time, the XML configuration is the only available way.  
3. Annotation configuration is often class-level, while XML configuration can be more flexible. For example, compared to the @Transaction transaction annotation, the transaction configuration using the aop/tx namespace is more flexible and simpler.  
4. Therefore, in implementing applications, we often need to use annotation configuration and XML configuration at the same time. For class-level configurations that do not change, we can give priority to annotation configuration; and for those third-party classes and configurations that are prone to adjustment, priority should be given. Consider using XML configuration. Spring will combine the meta information of these two configuration methods before implementing bean creation and bean injection. 


Summary:
Therefore, in implementing applications, we often need to use both annotation configuration and XML configuration. For class-level configurations that do not change, we can give priority to annotation configuration; for those third-party classes and configurations that are prone to adjustment, priority should be given. Consider using XML configuration. Spring will combine the meta information of these two configuration methods before implementing bean creation and bean injection. 

Reprinted from: http://blog.csdn.net/lf_software_studio/article/details/8256510

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326944231&siteId=291194637