Student programming ability improvement platform source code analysis Service layer source code analysis

preface

2021SC@SDUSC

summary

Following the first project overview and the analysis of the source code of the Controller layer, we have a certain understanding of the use of the key code and its internal implementation principle. Next, we will transition from the Controller layer to the Service layer according to the code call process. This is because after the Controller layer receives the request, we need to call the services of the Service layer, that is, the Service layer for processing, Instead of direct data operation, we will focus on the key code of the Service layer and its internal implementation principle in the next few articles

Source code

The source code is as follows:

@Service
public class BindService {
    @Autowired
    private BindMapper bindMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Transactional
    public Integer bindStuNum(StudentBind studentBind) throws DuplicateKeyException {
        if (UserUtil.getCurrentUserId() != null) {
            studentBind.setUserId(UserUtil.getCurrentUserId());
            if (bindMapper.validateStudentBind(studentBind) > 0) {
                roleMapper.insertRoleUserLink(studentBind.getUserId(), 3);
                UserInfo info = userInfoMapper.selectByUserId(UserUtil.getCurrentUserId());
                info.setStuNum(studentBind.getStuNum());
                info.setRealName(studentBind.getName());
                userInfoMapper.updateUserInfo(info);
                return 1;
            } else {
                return 0;
            }
        }
        return null;
    }

}

We can see that the Service layer provides methods for the call of the Controller layer and provides certain logical processing to call the methods of the Mapper data layer to obtain data.

Here are some key codes, but not many. We need to understand the following points:

1.@Service

2.@Transactional

3. Methods involving entity classes

4.@Autowired (previously analyzed, omitted)

These points will be analyzed one by one below.

@Service annotation

usage method

Comments before the declaration of the service class are as follows:

@Service
public class BindService {
    

}

source code

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

Analysis principle

You can see that its implementation is similar to @ Component, @ Controller, @ repository and other implementations,

@The @ Component annotation is marked on the service @ controller @ repository annotation, and they are equivalent

Just for hierarchical annotation, the implementation principle is: register beanDefiniton in the IOC container, and the background is a user-defined label, which is resolved according to the user-defined label explained earlier

For the analysis process, please refer to:

@Component parsing process

@Transactional annotation

usage method

@Transactional is the annotation configuration method of declarative transaction management in spring.

@Transactional annotations can help us to manage the operations of opening, committing or rolling back transactions through aop. Eliminates duplicate transaction management logic.

Examples are as follows:

 @Transactional
    public Integer bindStuNum(StudentBind studentBind) throws DuplicateKeyException {
        if (UserUtil.getCurrentUserId() != null) {
            studentBind.setUserId(UserUtil.getCurrentUserId());
            if (bindMapper.validateStudentBind(studentBind) > 0) {
                roleMapper.insertRoleUserLink(studentBind.getUserId(), 3);
                UserInfo info = userInfoMapper.selectByUserId(UserUtil.getCurrentUserId());
                info.setStuNum(studentBind.getStuNum());
                info.setRealName(studentBind.getName());
                userInfoMapper.updateUserInfo(info);
                return 1;
            } else {
                return 0;
            }
        }
        return null;
    }

source code

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package org.springframework.transaction.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    @AliasFor("transactionManager")
    String value() default "";

    @AliasFor("value")
    String transactionManager() default "";

    String[] label() default {};

    Propagation propagation() default Propagation.REQUIRED;

    Isolation isolation() default Isolation.DEFAULT;

    int timeout() default -1;

    String timeoutString() default "";

    boolean readOnly() default false;

    Class<? extends Throwable>[] rollbackFor() default {};

    String[] rollbackForClassName() default {};

    Class<? extends Throwable>[] noRollbackFor() default {};

    String[] noRollbackForClassName() default {};
}

Analysis principle

First of all, if you know the principle of aop implementation in spring, you should know that if you want to proxy a method, you must define a pointcut.

The same is true in the implementation of @ Transactional. spring defines the tangent point with @ Transactional annotation as the implantation point for us, so that we can know that the method marked by @ Transactional annotation needs to be proxy.
With the aspect definition, during the initialization of spring beans, you need to proxy the instantiated beans and generate proxy objects.
In the proxy logic for generating proxy objects, when making method calls, you need to obtain the aspect logic first. The aspect logic of @ Transactional annotation is similar to @ Around, which implements a similar proxy logic in spring.

Specific code process reference:

spring source code reading -- @ transactional implementation principle_ Gaga's blog - CSDN blog_@ Implementation principle of transactional annotation

Entity class method

usage method

Call the initialization, get and set methods of the entity class, as follows:

 UserInfo info = userInfoMapper.selectByUserId(UserUtil.getCurrentUserId());
                info.setStuNum(studentBind.getStuNum());
                info.setRealName(studentBind.getName());

source code

package cn.sdu.sdupta.domain;

public class UserInfo {
    private Integer userId;

    private String username;

    private String realName;

    private String headImage;

    private String nickname;

    private String stuNum;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getRealName() {
        return realName;
    }

    public void setRealName(String realName) {
        this.realName = realName;
    }

    public String getHeadImage() {
        return headImage;
    }

    public void setHeadImage(String headImage) {
        this.headImage = headImage;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public String getStuNum() {
        return stuNum;
    }

    public void setStuNum(String stuNum) {
        this.stuNum = stuNum;
    }
}

Analysis principle

Through the initialization method of entity class and user-defined get and set method, the data class is established and assembled to realize data encapsulation and docking with MYBATIS

summary

This is the end of the source code analysis of the service layer

We found that it is necessary to have a deep understanding of the underlying implementation mechanism of some annotations and classes

It is helpful for us to improve our code analysis ability and deepen our personal code understanding

The next analysis is expected to analyze the mapper layer code. Thank you for reading

reference material

@Implementation principle of Component, @ service, @ autowired and other annotations_ 3075763007 blog - CSDN blog_@ autowired annotation principle
spring source code reading -- @ transactional implementation principle_ Gaga's blog - CSDN blog_@ Implementation principle of transactional annotation
 

Keywords: Java

Added by omidh on Sun, 31 Oct 2021 21:59:12 +0200