This article focuses on the common ways Spring uses annotations to assemble beans, including @Component, @Repository, @Service, @Controller, @Autowired, @Resource, and @Qualifier.
preface
At present, I have learned Java for a period of time, but I am not used to all kinds of annotations in Java, because it contains too many things, and then the posture of use is also different. Today, I will simply make a summary and record, and after sweeping a blind, the subsequent use will be unimpeded.
What are annotations
The traditional Spring approach of using.xml files to inject beans or to configure AOP or things has two disadvantages:
- If everything was configured in an.xml file, the.xml file would be huge; If you separate the.xml files as required, there will be too many.xml files, which will make the configuration files less readable and maintainable.
- Switching between.java files and.xml files during development is cumbersome, and this mental incoherence reduces development efficiency.
To address both of these issues, Spring has introduced annotations that are tightly integrated with Java beans in the form of “@xxx”, greatly reducing the size of configuration files and increasing the readability and cohesiveness of Java beans.
Commonly used annotations
The following is a direct copy of the Chinese language interpretation:
- @Component: You can use this annotation to describe beans in Spring, but it is a generic concept that represents only a Component (Bean) and can be applied at any level. To use it, simply annotate the annotation on the corresponding class.
- @Repository: Identifies classes in the data access layer (DAO layer) as beans in Spring and has the same functionality as @Component.
- @service: Typically at the Service layer, it identifies business layer classes as Beans in Spring, with the same functionality as @Component.
- @Controller: usually applied to the control layer (e.g. Struts2 actions) to identify the control layer class as a Spring Bean, which has the same functionality as @Component.
- @autowired: used to annotate Bean attribute variables, attribute Set methods and constructors, and cooperate with the corresponding annotation processor to complete the automatic configuration of Bean. The default assembly is based on the type of Bean.
- @Resource: Does the same thing as Autowired. The difference is that @AutoWired is assembled by default by Bean type, while @Resource is assembled by default by Bean instance name.
- @Qualifier: Used in conjunction with the @AutoWired annotation, the default assembly by Bean type is changed to assembly by the instance name of the Bean, which is specified by the @qualifier annotation parameter.
Don’t use annotations
Take a look at a Spring example that uses no annotations and change it to an annotated version to see the difference between using and not using annotations. Define cat and dog first:
@ToString
public class Cat {
private String catName = "Luo Xiaohei";
}
Copy the code
@ToString
public class Dog {
private String dogName = "Prosperous wealth.";
}
Copy the code
Redefine pets:
@Data
public class Pets {
private Cat cat;
private Dog dog;
public static void main(String args[]) {
ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");
Pets pets=context.getBean("pets",Pets.class);
System.out.println(pets.toString());
}
}
/ / output:
// Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
Copy the code
Note that I use the @data annotation here, mainly using the getxxx() and setxxx() methods, because the Spring framework requires annotation injection. Since there are no annotations, we need to configure the XML file as follows:
<bean id="pets" class="com.java.annotation.spring.bean.test1.Pets" >
<property name="cat" ref="cat" />
<property name="dog" ref="dog" />
</bean>
<bean id="cat" class="com.java.annotation.spring.bean.test1.Cat" />
<bean id="dog" class="com.java.annotation.spring.bean.test1.Dog" />
Copy the code
Member variables use annotations
Here we use the @autowired annotation, and of course we can use the @Resource annotation. The difference will be explained later. Introducing annotations simplifies XML configuration files as follows:
<bean id="pets" class="com.java.annotation.spring.bean.tes1.Pets" />
<bean id="cat" class="com.java.annotation.spring.bean.test1.Cat" />
<bean id="dog" class="com.java.annotation.spring.bean.test1.Dog" />
Copy the code
Here we just add the @autowired annotation to Cat and Dog to automatically find the corresponding class according to the type of the variable, and then load it:
@Data
public class Pets {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
public static void main(String args[]) {
// main(
Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
}
}
Copy the code
Class uses annotations
We can annotate Dog and Cat classes with @service to simplify the XML configuration as follows:
<bean id="pets" class="com.java.annotation.spring.bean.tes1.Pets" />
Copy the code
The following is the correct way to annotate a class with @service. Of course, you can also use @Component, @repository, @service, and @Controller. The differences are similar, but the usage is less formal.
@Data
@Service
public class Cat {
private String catName = "Luo Xiaohei";
}
Copy the code
@Data
@Service
public class Dog {
private String dogName = "Prosperous wealth.";
}
Copy the code
Pets will remain the same as the example above. Of course, you can remove the Pets configuration in XML and just use the @service annotation for Pets, similar to Cat and Dog:
@Data
@Service
public class Pets {
// Internal code omitted
}
Copy the code
There was a huge bug that stuck with me for over an hour. I needed to configure the code path for annotation scanning in the configuration file, otherwise the program would run and tell me that annotations for this class could not be found.
For example, my project directory is under “com.java.annotation”, so you need to configure that path:
<! Use the context namespace to tell Spring to scan the specified directory for annotation parsing.
<context:component-scan base-package="com.java.annotation"/>
Copy the code
Interface injection
We can abstract an interface to Animal for Dog and Cat (I’m not using the interface this way, I’m just giving an example) as follows:
public interface Animal {
public String food = null;
}
Copy the code
Here are Cat and Dog:
@Data
@Service
public class Cat implements Animal {
private String catName = "Luo Xiaohei";
}
Copy the code
@Data
@Service
public class Dog implements Animal {
private String dogName = "Prosperous wealth.";
}
Copy the code
The important thing about this is that injection via @service does two things:
- It is important to declare Pets. Java is a bean, so other classes can use @AutoWired to inject Pets as a member variable automatically;
- Pets. The id of Java in the bean is “Pets”, which is the class name and starts with a lowercase letter.
Define variables with interface names
Our member variable definition can use the interface Animal, but the variable names must be dog and cat, because Spring’s injection of dog and cat is called dog and cat:
@Data
public class Pets {
@Autowired
private Animal dog;
@Autowired
private Animal cat;
// main(
Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
}
Copy the code
If I change the variable name to dog1, it looks like this:
@Data
public class Pets {
@Autowired
private Animal dog1; // If you use it incorrectly, you will get an error!!
@Autowired
private Animal cat;
}
Copy the code
Can not find dog1 corresponding to the injected class.
However, the above way is not recommended to use, on the one hand, it is not easy to understand, on the other hand, it is easy to leave pits for others! If you must use an interface to define variables, use the @qualifier annotation.
Introduce the @qualifier annotation
Used in conjunction with the @AutoWired annotation, the @Qualifier annotation changes the default assembly by Bean type to assembly by the instance name of the Bean, which is specified by the @Qualifier annotation parameter.
@Data
public class Pets {
@Autowired
@Qualifier("dog")
private Animal dog1;
@Autowired
private Animal cat;
// main(
Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
}
Copy the code
The best way to define a variable is to use the class name directly.
Define variables with class names
@Data
public class Pets {
@Autowired
private Dog dog1;
@Autowired
private Cat cat1;
// main(
Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
}
Copy the code
So this is pretty straightforward, if I specify dog1 by Dog and cat1 by Cat, then I don’t have to worry about the variable name.
Custom injection name
If you want to specify the injection name yourself, you need to use the @resource annotation, just make the following changes in the Dog and Cat classes:
@Data
@Service("miniCat")
public class Cat implements Animal {
private String catName = "Luo Xiaohei";
}
Copy the code
For Cat our injection is called miniCat, so we can specify miniCat as follows:
@Data
public class Pets {
@Resource
private Dog dog1;
@Resource(name = "miniCat") // It can only be miniCat, otherwise an error will be reported
// @resource (type = cat.class) //
// @resource //
private Cat cat1;
// main(
Pets(cat= cat (catName= cat), dog= dog (dogName= fortune))
}
Copy the code
There should be more postures that are used, and I’m not going to list them, but whatever the variations are, you just need to know the order in which @Resource is assembled, and the difference between @Resource and @Autowired, and it’s pretty easy to understand.
@Resource vs @Autowired
The assembly sequence of @Resource is as follows:
- There is nothing behind @resource. By default, the bean is matched by the name attribute. If not, the bean is matched by type.
- If name or type is specified, the bean is matched according to the specified type.
- If name and type are specified, the bean will be matched against the specified name and type. Any mismatches will result in an error.
Then, let’s make a distinction between @autowired and @Resource annotations:
- By default, @autowired matches beans as byType, and @Resource matches beans as byName
- @autowired is a Spring annotation and @resource is a J2EE annotation. The package names of these two annotations will be clear when you import them
Spring is third-party and J2EE is Java’s own thing, so it is recommended to use the @Resource annotation to reduce coupling between your code and Spring.
To sum up:
@Resource is name and type, @Autowired is type, so in general it’s better to use @Resource.
conclusion
The article explains the usage of @service, @autowired, @Resource and @qualifier in detail, which focuses on the difference between @autowired and @Qualifier. The @Component, @Repository, and @Controller annotations have the same meaning as the @Service annotations. However, when we write code, we will layer the DAO layer, the Service layer, and the Action layer. You can use @repository, @service, @controller, and the @component can be applied at any level. So it looks like there are seven annotations, but you can understand there are only four.
Welcome everyone to like a lot, more articles, please pay attention to the wechat public number “Lou Zai advanced road”, point attention, do not get lost ~~