Efficient development: full analysis of Spring's various annotations

Efficient development: full analysis of Spring's various annotations

table of Contents

I. Introduction

2. Common annotations: @Autowired annotation

2.1 Introduction: Do not use any annotations (comparison with the annotations used later)

2.2 @Autowired annotation

2.2.1 @Autowired labels class member variables

2.2.2 @Autowired annotates the setter method (set value injection)

2.2.3 @Autowired annotates the constructor (construction injection)

3. Common annotations: @Component annotation

3.1 @Component annotation: Student does not refer to class member variables

3.2 @Component annotation: Student refers to class member variables teacher and course

4. Common annotations: @Repository annotation, @Service annotation, @Controller annotation

4.1 @Repository annotation

4.2 @Service annotation

4.3 @Controller annotation

5. Other annotations: @Resource annotation, @PostConstruct annotation and @PreDestory annotation

5.1 @Resource annotation

5.1.1 @Resource annotation marks class member variables

5.1.2 @Resource annotation marks setter methods

5.2 @PostConstruct annotation and @PreDestory annotation

6. summary


I. Introduction

The Spring container is an important container framework in Javaweb development. Its related configuration can be completed by xml configuration files, but also by related annotations. This article introduces various common annotations and very useful annotations of the Spring container, including

Common annotations: @Autowired annotation, @Component annotation, @Repository annotation, @Service annotation, @Controller annotation

Uncommon annotations (other annotations): @Resource annotation, @PostConstruct annotation and @PreDestory annotation

2. Common annotations: @Autowired annotation

2.1 Introduction: Do not use any annotations (comparison with the annotations used later)

The pojo class and configuration file applicationContext.xml are as follows:

package com.pojo; public class Student { private Teacher teacher; private Course course; public void setTeacher (Teacher teacher) { this .teacher = teacher; } public void setCourse (Course course) { this .course = course; } @Override public String toString () { return super .toString() + "-" + teacher + "-" + course; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <bean id= "student" class = "com.pojo.Student" > <property name= "teacher" ref= "teacher" ></property> <property name= "course" ref= "course" ></property> </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

main function

package com.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.pojo.Student; public class TestSpring { public static void main (String[] args) { //Access applciationContext.xml //ApplciatinoContext is an interface in Spring, it has two implementation classes ClassPathXmlApplicationContext and FileSystemXmlApplicationContext //ClassPathXmlApplicationContext is generally used in Java to create Spring container ApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml" }); Student student = (Student) context.getBean( "student" ); System.out.println(student); } } Copy code

Output:

com.pojo.Student@6f1fba17 - com.pojo.Teacher@185d8b6 - com.pojo.Course @ 67,784,306 copy the code

2.2 @Autowired annotation

Function/purpose: @Autowired can mark class member variables, methods and constructors to complete the work of automatic assembly.

2.2.1 @Autowired labels class member variables

@Autowired annotates the class member variable, then the class member variable no longer needs a setter (setting injection). The configuration file applicationContext.xml can remove the <property.../> tag of the Student class reference class member variable:

package com.pojo; import org.springframework.beans.factory.annotation.Autowired; public class Student { @Autowired private Teacher teacher; @Autowired private Course course; @Override public String toString () { return super .toString() + "-" + teacher + "-" + course; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Output:

com.pojo.Student@6f1fba17 - com.pojo.Teacher@185d8b6 - com.pojo.Course @ 67,784,306 copy the code

For classes in pojo, after using @Autowired annotations on class member variables, there is no need to provide setter-getter methods for them because they can be automatically assembled.

How to configure in the configuration file applicationContext.xml, remove the <property.../> tags of the reference class member variables of the Student class, and add <context:annotation-config/> to tell Spring to use annotations for configuration.

About <context:annotationconfig/>:

<context:annotationconfig/> will implicitly register with the Spring container 

AutowiredAnnotationBeanPostProcessor
,
CommonAnnotationBeanPostProcessor
,
PersistenceAnnotationBeanPostProcessor
 as well as
equiredAnnotationBeanPostProcessor
 These 4 BeanPostProcessors. Means to tell Spring to use annotations for configuration.

2.2.2 @Autowired annotates the setter method (set value injection)

As mentioned above, if you use @Autowired to annotate class member variables, you don't need a setter because it can be automatically assembled. In fact, liberating the @Autowired annotation to the setter has the same effect as annotating @Autowired to the class member variable, both of which are automatic assembly.

package com.pojo; import org.springframework.beans.factory.annotation.Autowired; public class Student { private Teacher teacher; private Course course; @Autowired public void setTeacher (Teacher teacher) { this .teacher = teacher; } @Autowired public void setCourse (Course course) { this .course = course; } @Override public String toString () { return super .toString() + "-" + teacher + "-" + course; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Output:

com.pojo.Student@6f1fba17 - com.pojo.Teacher@185d8b6 - com.pojo.Course @ 67,784,306 copy the code

Therefore, liberating the @Autowired annotation to the setter has the same effect as annotating @Autowired to the class member variable, both of which are automatic assembly.

2.2.3 @Autowired annotates the constructor (construction injection)

What if @Autowired is marked on the constructor? If it is a parameterless constructor, it is meaningless to label it, because it does not have the effect of setting the value, so the constructors marked with @Autowired are all parameterized constructors, and the value is set using construction injection.

package com.pojo; import org.springframework.beans.factory.annotation.Autowired; public class Student { private Teacher teacher; private Course course; @Autowired public Student (Teacher teacher, Course course) { this .teacher = teacher; this .course = course; } @Override public String toString () { return super .toString() + "-" + teacher + "-" + course; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Output:

com.pojo.Student@6f1fba17 - com.pojo.Teacher@185d8b6 - com.pojo.Course @ 67,784,306 copy the code

Therefore, liberating the @Autowired annotation to the constructor is the same as annotating @Autowired to the class member variable, both of which are automatic assembly.

Attachment: If there are 0 <bean../> or two <bean../> and pojo corresponding Beans in the configuration file applicationContext.xml, an error will be reported. Let's look at the following:

(1) 0 <bean../> in applicationContext.xml corresponds to the Bean class of pojo.

error: In the Thread Exception "main" org.springframework.beans.factory.BeanCreationException copy the code

Solution: There is only one, that is, add <bean../> to the applicationContext.xml file. (Note that with regard to the use of @Autowired(required = false), the use of automatic injection and non-injection is only used during development or testing. I don t think it s a fundamental solution. The fundamental solution is To add the corresponding <bean../>) in the configuration file applicationContext.xml)

(2) The two <bean../> in applicationContext.xml correspond to the Bean class of pojo.

appear

BeanCreationException
 Exception, this exception only appears in the lower version of Spring. The solution is to add @Qualifier("xxx") to specify the name of the injected bean. This exception will not appear in the higher version of Spring, so skip it.

3. Common annotations: @Component annotation

Although we can pass 

@Autowired
 or 
@Resource
 The automatic injection function is used in the Bean class, but the Bean is still defined in the XML file through <bean>-that is, the Bean is defined in the XML configuration file through
@Autowired
 or 
@Resource
 Provide automatic injection function for Bean member variables, method input parameters or constructor input parameters. Can you also define Bean through annotations, and completely remove the Bean-defined configuration from the XML configuration file? The answer is yes, we provide it through Spring 2.5
@Component
 Annotations can achieve this goal.

@Component only needs to be at the class definition, using @Component annotation to instantiate a class as a Bean in the Spring container, which is equivalent to <bean id="" class=""/> in the configuration file

3.1 @Component annotation: Student does not refer to class member variables

package com.pojo; import org.springframework.stereotype.Component; @Component("student") public class Student { private int age = 20 ; private String name = " " ; public void setAge ( int age) { this .age = age; } public void setName (String name) { this .name = name; } @Override public String toString () { return super .toString() + "-" + age + "-" + name; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:component-scan base- package = "com.pojo"/> </beans> Copy code

Output:

com.pojo.Student@30b8a058 - 20 is - Bob duplicated code

Therefore, the @Component annotation implements the principle of removing <bean../> in applicationContext.xml.

In applicationContext.xml, after using <context:component-scan/>, you can remove <context:annotation-config/>.

3.2 @Component annotation: Student refers to class member variables teacher and course

(Because the main function needs to print out the results, and when using @Component, delete all the <bean.../> in the configuration file applicaitonContext.xml, and it is impossible to set the Student's reference to Teacher and Course, so you need to quote Class member variables, you must use @Autowired when using @Component)

package com.pojo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("student") public class Student { @Autowired private Teacher teacher; @Autowired private Course course; @Override public String toString () { return super .toString() + "-" + teacher + "-" + course; } } Copy code
package com.pojo; import org.springframework.stereotype.Component; @Component public class Course { } Copy code
package com.pojo; import org.springframework.stereotype.Component; @Component public class Teacher { } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:component-scan base- package = "com.pojo"/> </beans> Copy code

Output:

com.pojo.Student@5d76b067 - com.pojo.Teacher@2a17b7b6 - com.pojo.Course@4f063c0a copy the code

It is the same as the first one without any annotations, and the effect is achieved. Therefore, @Component annotation implements the principle of removing <bean../> in applicationContext.xml.

An additional point: About <context:annotation-config/> and <context:component-scan/>.

 The <context:component-scan/> configuration item not only enables the function of scanning class packages to implement annotation-driven bean definitions, but also enables the function of annotation-driven automatic injection (that is, it also implicitly registers internally

AutowiredAnnotationBeanPostProcessor
 with
CommonAnnotationBeanPostProcessor
), so when using <context:component-scan/>, you can remove <context:annotation-config/>. As shown in the code above, remove <context:annotation-config/> and leave only <context:component-scan base-package="xxx.xxx"/>

4. Common annotations: @Repository annotation, @Service annotation, @Controller annotation

4.1 @Repository annotation

The @Repository annotation can only be annotated in the Dao layer, and is used to identify the class of the data access layer (DAO layer) as Spring Bean. Specifically, you only need to mark the annotation on the DAO class. Such as:

public class StudentDaoImpl implements StudentDao { } Copy code

The role of @Repository is not only to recognize the class as a Bean, but also to encapsulate the data access exception thrown in the marked class as Spring's data access exception type. Spring itself provides a rich data access exception structure that has nothing to do with specific data access technology, which is used to encapsulate exceptions thrown by different persistence layer frameworks, making exceptions independent of the underlying framework.

4.2 @Service annotation

@Service usually acts on the business layer, @Service is a special form of @Component annotation (that is, in the form of the service layer), and its function is the same as the @Component annotation (that is, the Service definition configuration is removed from the xml configuration file), even if It does not matter if it is changed to the @Component annotation. In project development, we use @Service instead of @Component in the service layer class because it specifies the intent in a better way, telling other colleagues or subsequent maintainers that this is a Service service, which is the Service service layer.

4.3 @Controller annotation

@Constroller usually acts on the control layer, but currently the function is the same as @Component (that is, the Service definition configuration is removed from the xml configuration file), even if it is changed to the @Component annotation, it does not matter. In project development, we use @Controller instead of @Component in the service layer class because it specifies the intent in a better way, telling other colleagues or subsequent maintainers that this is a controller, and this is the Controller control layer.

In addition, the @Controller annotation is an annotation of SpringMVC. Spring and SpringMVC are each other's parent and child containers. Spring is the parent container. The parent container cannot access the annotations of the child container, so it cannot be demonstrated.

5. Other annotations: @Resource annotation, @PostConstruct annotation and @PreDestory annotation

5.1 @Resource annotation

@Resource
 Is equivalent to 
@Autowired
,only 
@Autowired
 Automatically inject according to byType, and
@Resource
 It is automatically injected according to byName by default.
@Resource
 Two attributes are more important, namely name and type. Spring will
@Resource
 The name attribute of the annotation resolves to the name of the Bean, and the type attribute resolves to 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 annotation marks class member variables or setter methods to complete the work of automatic assembly.

5.1.1 @Resource annotation marks class member variables

package com.pojo; import javax.annotation.Resource; public class Student { @Resource private Course course; @Resource private Teacher teacher; @Override public String toString () { return super .toString() + "-" + course + "-" + teacher; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation =" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Output:

com.pojo.Student@5ec0a365 - com.pojo.Course@4fe3c938 - com.pojo.Teacher@5383967b copy the code

Summary: The use of @Resource and @Autowired are basically the same for developers, except 

@Autowired
 Automatically inject according to byType, and
@Resource
 It is automatically injected according to byName by default. But remember: @Resource annotation cannot mark the constructor.

5.1.2 @Resource annotation marks setter methods

package com.pojo; import javax.annotation.Resource; public class Student { private Course course; private Teacher teacher; @Resource public void setCourse (Course course) { this .course = course; } @Resource public void setTeacher (Teacher teacher) { this .teacher = teacher; } @Override public String toString () { return super .toString() + "-" + course + "-" + teacher; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Output:

com.pojo.Student@5f9d02cb - com.pojo.Course@63753b6d - com.pojo.Teacher@6b09bb57 copy the code

Summary: The use of @Resource and @Autowired are basically the same for developers, except 

@Autowired
 Automatically inject according to byType, and
@Resource
 It is automatically injected according to byName by default. But remember: @Resource annotation cannot mark the constructor

@Resource annotation marks the constructor: @Resource annotation cannot mark the constructor

Summary: The use of @Resource and @Autowired are basically the same for developers, except 

@Autowired
 Automatically inject according to byType, and
@Resource
 It is automatically injected according to byName by default. But remember: @Resource annotation cannot mark the constructor

5.2 @PostConstruct annotation and @PreDestory annotation

These two comments can only be applied to methods. The method annotated with @PostConstruct will be called after the class is instantiated, and the method annotated with @PreDestroy will be called before the class is destroyed.

package com.pojo; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class Student { private Course course; private Teacher teacher; @PostConstruct public void postConstruct1 () { System.out.println( "postConstruct Function is called" ); } @PreDestroy public void preDestroy1 () { System.out.println( "preDestroy Function is called" ); } public void setCourse (Course course) { this .course = course; } public void setTeacher (Teacher teacher) { this .teacher = teacher; } @Override public String toString () { return super .toString() + "-" + course + "-" + teacher; } } Copy code
<?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:aop= "http://www .springframework.org/schema/aop" xmlns:tx= "http://www.springframework.org/schema/tx" xmlns:context= "http://www.springframework.org/schema/context" xsi:schemaLocation = " http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <context:annotation-config/> <bean id= "student" class = "com.pojo.Student" > <property name= "teacher" ref= "teacher" ></property> <property name= "course" ref= "course" ></property> </bean> <bean id= "teacher" class = "com.pojo.Teacher" ></bean> <bean id= "course" class = "com.pojo.Course" ></bean> </beans> Copy code

Add a main function, and finally context.destroy();

public class TestSpring { public static void main (String[] args) { //Access applciationContext.xml //ApplciatinoContext is an interface in Spring, it has two implementation classes ClassPathXmlApplicationContext and FileSystemXmlApplicationContext //ClassPathXmlApplicationContext class is generally used in Java to create Spring container ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( new String[] { "applicationContext.xml" }); Student student = (Student) context.getBean( "student" ); System.out.println(student); context.destroy(); } } Copy code

Output:

postConstruct Function is called com.pojo.Student@ 50b494a6 -com.pojo.Course@ 3cef309d -com.pojo.Teacher@ 32709393 preDestroy Function is called Copy code

6. summary

This section introduces a number of commonly used annotations and very useful annotations in the Spring container, hoping to help Spring learners.

Code every day, make progress every day!