1
Abstract: spring is an indispensable framework in our web development. It always feels too cumbersome to configure beans based on the traditional xml method. The emergence of annotations after spring 2.5 can greatly simplify our configuration.

This article is shared from HUAWEI CLOUD COMMUNITY " How to Efficiently Improve the Efficiency of Java Development-A Complete Course of Spring Annotation Development!" ", author: Grey Little Ape.

One, use annotations to identify components

In order to no longer declare class objects one by one in IOC, first, according to the different functions of each class, Spring first stipulates component-based annotations, which can be roughly divided into the following four types:

component: @Component

To identify a component managed by the Spring IOC container, we can also understand it as an annotation used by other components except the database layer, business logic layer, and control layer components.

layer components: @Respository

Identifies a persistence layer component managed by the Spring IOC container, which is generally used to mark the database layer

logic layer components: @Service

Identify a business logic layer component managed by the Spring IOC container,

④ Presentation layer controller component: @Controller

Identifies a presentation layer controller component managed by the Spring IOC container.

At the same time, you can add some parameters after these comments. For example, the more commonly used one is the value attribute in the parentheses of the comment to indicate the ID of the component in the container. If the value value is not set, the default ID is the class name The full name (the first letter is lowercase).

In the following example, we add a @Respository annotation to a Dao layer component

/**
 * 数据库层注解
 * */
@Repository
public class BookDao {
    public void saveBook() {
        System.out.println("bookDao中的图书已保存...");
    }
}

Through these four annotations, we can first classify all the components one by one. In terms of why annotations are used for classification, in the final analysis, it is actually for the convenience and quickness to know which class does what type of function, and at the same time, it is convenient to add components to the IOC container through these four annotations.

So you can also understand these four annotations as an "ID card" distributed by Spring to different functional components. Only if you have these four "ID cards", then this component can be added to the IOC container.

One thing to note here: In fact, Spring does not have the ability to identify whether a component is the type it is marking. will not produce any errors even if the @Respository annotation is used on a presentation layer controller component, so @ The Respository, @Service, and @Controller annotations are just for developers to clarify the role of the current component. It is convenient to add components to the container.

Second, component scanning

1. Ordinary scan

Now, all the components are classified in detail, but this is equivalent to adding all the components to the IOC container? If this is the case, then we have truly realized the low-code era...

So now how should we add components with annotations to the IOC container? Here, Spring provides a package scanning function in the IOC. By this name, we can know that Spring can automatically scan the components marked with these four annotations in the entire project and add them to the IOC container.

The specific operation for packet scanning is as follows:

Package scanning depends on the Context namespace, so you need to add the namespace to the IOC. There are two ways to add the namespace. One is to add the following code to the IOC header file:

xmlns:context="http://www.springframework.org/schema/context"

But because it’s hard to remember, it’s not recommended.

The other is to directly click on the Namespaces at the bottom of the interface, find and check Context in it,
image.png

​The code for packet scanning in the container is:

<context:component-scan base-package="com.spring"></context:component-scan>

The base-package attribute specifies a base package that needs to be scanned, and the Spring container will scan all classes in this base package and its sub-packages. When you need to scan multiple packages, you can use commas to separate them. For example, the above code is to scan all the classes under the com.spring package.

2. Include and exclude specific components

However, the scope of such scanning is sometimes large, so can the scope of packet scanning be reduced? Of course it is possible.

If you only want to scan a specific class instead of all classes in the base package, you can use the resource-pattern attribute to filter specific classes, such as:

<context:component-scan base-package="com.atguigu.component" resource-pattern="autowire/*.class"/>

(1) Scan contains specific components

If we just want to scan components that contain specific characteristics, then we can do the following:

<context:include-filter> child node indicates the target class to be included

But it should be noted that: because context:component-scan adds all the classes by default, it is useless to add on this basis. You need to add the attribute parameter use-default- to context:component-scan. filters, use-default-filters="true" means that all classes are added by default, and false means that all classes are not added.

The following code means to scan only the components that contain the features specified in the include-filter, where type is used to indicate what type of scanning expression is used, and expression is followed by an expression.

<context:component-scan base-package="com.spring" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>

(2) Scan to exclude specific components

If there are scans that include specific components, then there are scans that exclude specific components.

<context:exclude-filter> child node represents the target class to be excluded.

The following code means scanning other components except the following features.

<context:component-scan base-package="com.spring">
    <context:exclude-filter type="assignable" expression="com.spring.service.BookService"/>  
</context:component-scan> 

At the same time, there can be several include-filter and exclude-filter sub-nodes under the component-scan, to indicate which components can be included or excluded.

The type and function of the filter expression filled in the type mentioned above are as follows:
image.png

The top two are most commonly used, and the following three are rarely used:

type="aspectj" aspectj expression

type="custom" defines a TypeFile, write a class definition which one to use

type="regex" uses regular expressions

Note that there is a bug: Some friends write perfect annotations and scans when developing annotations, but they just don’t work. The reason may be the lack of a corresponding unique jar package, and an additional aop package needs to be imported here.

spring-aop-4.0.0.RELEASE.jar​

At this point, the operation of adding the component to the container is complete,

After we have successfully added the component, we can see a small S icon in the upper right corner of the component icon. This time it means that the component has been successfully added to the container.

3. Three steps to implement annotations

Summarize the three steps of implementing annotations:

  • Add context dependency

    • context:component-scan
  • Add corresponding annotations to the class

    • Import the aop package
    • spring-aop-4.0.0.RELEASE.jar

Three, automatic assembly of components

But is this the end? Is it so easy? Is the scope and life cycle of the bean that I learned before is useless? of course not! ! ! More importantly, the components have not been acquired yet! ! !

Then, let’s talk to you about the high-end operations developed with annotations, and let you know how fragrant it is to use annotations! ! !

When we usually use classes, we will inevitably call other custom classes in the class.

So if we instantiate these components that need to be instantiated in the class one by one, is it too troublesome? Hey, how could clever and witty programmers not think of this! So the automatic assembly of components appeared,​

In spring, we can automatically assemble components in the form of annotations, so how do we assemble components?

In fact, when the package to be scanned is specified in the IOC, the <context:component-scan> element will automatically register a bean post processor: an instance of AutowiredAnnotationBeanPostProcessor. The post processor can automatically assemble the attributes annotated with @Autowired, @Resource, or @Inject.

The above three annotations @Autowired, @Resource or @Inject are the most commonly used annotations when we perform component automatic assembly.

Let me introduce to you the specific use of these three annotations.

1. @autowired annotation

@autowired annotation can realize automatic assembly according to type. Whether it is a constructor, ordinary fields (even non-public), or all methods with parameters, @Autowired annotations can be applied

By default, all attributes annotated with @Autowired need to be set. When Spring cannot find a matching bean assembly attribute, it will throw an exception.

(1)@autowired assembly principle

Next, let me tell you in detail about the assembly principle of the @autowired annotation:

1. When using automatic assembly, first find the corresponding components in the container according to the type, which is similar to

getBean("bookService.class"),
2. Throw an exception if it is not found, and assign a value if it finds one

3. If more than one is found, then there is a certain assembly basis, not just one for assembly.

First, continue to search based on the attribute name as the ID. If the component corresponding to the attribute name is found, it will be assembled. If it is not found, error will be reported. The reason for the error 16113838906239 is: when the variable name is used as the id for matching, the corresponding attribute name

(2) @Qualifier specifies the assembly ID

In fact, there is another solution to this kind of error: use @Qualifier("bookService") to specify the search ID, and assemble when found, and report the error if it is not found. The code example for specifying the search ID is as follows:

// 添加注解表示自动装填
@Autowired
@Qualifier("bookdao")
private BookDao bookDao;

(3) required—assembly error resolution

Then, if you can't find it, you will report an error every time. Doesn't the program crash? What should we do in such a situation? In fact, there is another way to solve the error not found: use the required parameter,

@Autowired(required=false) required=false means that if it is not found, it will assemble null

Anyway, the basis of assembly is to search for a suitable assembly object according to a variety of rules, until the search is successful, it returns null if it is not successful.

(4) Automatic assembly of special attributes

The above are the basic principles and steps of using @Autowired annotations. Our annotation development in spring is very powerful. Let's talk about the assembly of several special attributes.

@Autowired annotation can be applied to the attributes of the array type, at this time Spring will automatically assemble all matching beans.

@Autowired annotation can also be applied to collection properties, at this time Spring reads the type information of the collection, and then automatically assembles all compatible beans.

@Autowired annotation is used on java.util.Map, if the key value of the Map is String, then Spring will automatically assemble a bean compatible with the value type as the value, and use the id value of the bean as the key.

In this way, the automatic assembly of the @Autowired annotation is very powerful, and my mother will no longer have to worry about my new object in the future! ! !​

2. @Resource annotation

The @Resource annotation requires a bean name attribute. If the attribute is empty, the variable or method name at the annotation will be automatically used as the bean name.

3. @Inject annotation

The @Inject and @Autowired annotations also inject matching beans by type, but there is no reqired attribute.

above 16113838906395 are the three annotations used in automatic assembly, here is a summary,

@autoWried comes with spring, which is more powerful and can achieve required=false

@Resource also comes with java and is more extensible, so if you switch to another container framework, @Resource can still be used, and @Inject and @Autowired annotations are the same as injecting matching beans by type, but there is no required attribute . In fact, in daily development, the most commonly used and most powerful annotation is the @Autowired annotation. So remember this one basically.

Then summarize the benefits of using annotations. The main thing is to save the trouble of the new object. You can directly use an @Autowired annotation, and spring can automatically assign a value to the attribute. Generally speaking, adding the component to the IOC annotation and @Autowired is a combination in use.

Fourth, the small details of the use of annotations

In fact, there are some small details that need to be paid attention to when using annotations for development. I will summarize here for everyone.

1. Integrate multiple configuration files

When the project we are developing is too large, writing in a configuration file such as configuration sometimes cannot meet our needs, so Spring allows multiple configuration files to be imported into one file through <import> to integrate configuration files . In this way, when starting the Spring container, you only need to specify the merged configuration file. The resource attribute of the import element supports Spring's standard path resources,

In the following example, we have two configuration files springmvc.xml and spring.xml. Now we want to introduce spring.xml into springmvc.xml by writing the following code in springmvc.xml:

<import resource="spring.xml"/>

2. Path writing problem

For commonly used address writing in spring, sometimes you need to use classpath, and sometimes you need others. For different path writing, there are different meanings and uses: see the following table for details:
image.png

3. Problems when obtaining components

For the component added to the container using the annotation method, we can't see it in the IOC container, so how should we get it when we get it?

As we said above, if does not specify the id in the annotation, Spring will automatically set the full name of the component with the first letter in lowercase as the ID for each component (for example, the ID of the Book class is book by default) . The method of obtaining components in the container is the same as in the past, but if it is a single instance, it is generally recommended to use the class as a parameter to obtain it. like:

Book book = (Book)ioc.getBean(Book.class);

Five, write at the end

The above is all the knowledge points of Spring annotation development. Do you think that using annotation development is much more concise than native code. Annotation is also something that SSM framework and future development will often use?

Click to follow and learn about Huawei Cloud's fresh technology for the first time~


华为云开发者联盟
1.4k 声望1.8k 粉丝

生于云,长于云,让开发者成为决定性力量