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:

  1. 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.
  2. 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:

  1. There is nothing behind @resource. By default, the bean is matched by the name attribute. If not, the bean is matched by type.
  2. If name or type is specified, the bean is matched according to the specified type.
  3. 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:

  1. By default, @autowired matches beans as byType, and @Resource matches beans as byName
  2. @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 ~~