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:
@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:
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