Idea develops some small dry goods of springboot

1. Use lombok plugin

In the usual code writing, we have to write a lot of object classes such as javabean, pojo, etc., and also generate various setxxx, getxxx, tostring, hashcode, equal and other methods for various attributes. These are all regulations. Template method, or you may say that I used idea to automatically generate it for me, but this will also increase the code in the class, and using lombok can achieve the effect you want without writing such a code.

use:

   1. First add the coordinate dependency of lombok in maven's pom.xml

<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
</dependency>

2. Add a plug-in after the dependency comes in

Just download and restart the idea.

3. If you use the set method in the javabean you created, use the @setter annotation, and the get method is also the same. If both the set and get methods are required, use the @data annotation.

Corresponding to @ToString method, @EqualAndHashCode annotation, as the name knows.

 

2. Dynamically update the updateTime field in the database

Usually when we create a database table, we will add createTime and updateTime two fields, although you think these two fields are temporarily not used, but this is a good habit, and in the created SQL statement, these two The sql of each field is as follows:

`create_time` timestamp not null default current_timestamp comment '创建时间',
    `update_time` timestamp not null default current_timestamp on update current_timestamp comment '修改时间'

These two fields are of the time type, and createTime sets current_timestamp, that is, when each piece of data is added, this field is recorded to the database with the current time as the data, and the value of the field will not change due to update modification, while updateTime The difference with createTime is the current_timestamp on update current_timestamp is set. Each subsequent update of this setting will affect the value of this field, which is the current modification time.

So when we use springboot's jpa, when we update the data

@Test
    public void update() {
        ProductCategory productCategory = productCategoryDao.findOne(2);
        productCategory.setCategoryType(10);
        productCategoryDao.save(productCategory);
    }

For example, we first find out the object corresponding to this data, and then setxxx on this object, and then save you will find that the type in the database has changed, but the updateTime has not changed, it is still the original value, so we are in the database Setting the automatically modified attribute of the updateTime field is useless, because we found out the object, we just modified the type attribute of the object, and did not modify the value of updateTime, it seems wrong, not the current_timestamp on is set in the database Is update current_timestamp set? In fact, here we only need to add the annotation @DynamicUpdate to the javabean object. Add this annotation and then set current_timestamp on update current_timestamp in the database to realize that updateTime is automatically modified as we modify any field of this data. For the current time.

The use of three transactions @transactional

The use of transactions can help us easily achieve some data unification problems. In springboot, you can use the annotation @transactional to implement transactions.

For example, in my order creation business, first insert the product data of the order details, then calculate the total price of the order, and finally generate the total order, deducting the inventory, and for each step here, it should be packaged into a transaction to prevent There is an error in the database operation. For example, once the inventory is found to be insufficient in the deducted inventory, a rollback will occur, and the data previously inserted, updated and deleted will be restored to its original appearance.

There is another in the @transactional annotationThe propagation attribute, to describe the behavior of the transaction. The default is Propagation.REQUIRED. That is to say, if there is no current transaction, create a new transaction, otherwise join the transaction.

https://blog.csdn.net/nextyu/article/details/78669997   This is the usage of @transactional in springboot 

Four. WebSocket

WebSocket is a protocol that HTML5 began to provide for full-duplex communication on a single TCP connection. First of all, why do you need WebSocket? Http protocol is a stateless, connectionless, one-way application layer protocol. Once the connection is disconnected, the subsequent connections have nothing to do with the previous connection, so there is a drawback, that is, the server cannot Actively push information to the client. If you want to obtain the server's information in real time, you can use the polling method to request the server every few seconds, but this is too wasteful of resources, and it is a waste of traffic for mobile phones. The other is to establish a long connection with the server to implement the server's active push of information to the client, and WebSocket is born for this.

To develop WebSocket communication in springboot, first add dependencies

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

Then add the configuration class to enable WebSocket support

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

 Create a listening class for WebSocket

@Component
@ServerEndpoint("/webSocket")
@Slf4j
public class WebSocket {

    private Session session;

    public static CopyOnWriteArraySet<WebSocket> webSocketCopyOnWriteArraySet = new CopyOnWriteArraySet<>();

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        webSocketCopyOnWriteArraySet.add(this);
        log.error("【一个新的连接已建立】,连接总数为{}", webSocketCopyOnWriteArraySet.size());
    }

    @OnClose
    public void onClose() {
        webSocketCopyOnWriteArraySet.remove(this);
        log.error("【一个连接已断开】,连接总数为{}", webSocketCopyOnWriteArraySet.size());
    }

    @OnMessage
    public void onMessage(String message) {
        log.error("收到客户端发来的信息,信息内容为{}", message);
    }

    public void sendMessage(String message) {
        for (WebSocket webSocket : webSocketCopyOnWriteArraySet) {
            try {
                log.error("发送新的信息{},", message);
                webSocket.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}

In this monitoring class, you can monitor the operations of establishing connection, disconnecting, and sending and receiving information. There is a static collection to save each instance of WebSocket that establishes a connection between the client and the server. After the connection is successful, there will be A session object, which is used to push information to connected clients.

Js code in the client 

The name of each method corresponds to its intended operation. When the client receives a message, it will trigger the onmessage event, where we can operate the pop-up window, open the ringtone reminder, and so on.

5. Aspect-oriented AOP 

AOP is rarely used when writing code. Spring’s two core IOCs and AOPs can be used in projects such as permission checks. The aspect-oriented approach is to cut some repetitive codes horizontally. In the code we are running, the permission check is basically required for every URL, so AOP can achieve our needs more elegantly.

Let me talk about a few commonly used terms in AOP:

Joinpoint

The connection point refers to a specific location where the enhancement program is executed (where the enhancement operation is to be performed). Spring only supports the connection point of the method, which can only wait for these programs before the method is called, after the method is called, and when the method throws an exception. Execution point for weaving enhancement.

Pointcut

The point of contact is a set of connection points. That is, a range is pointed to determine which connection points.

Advice

The enhancement is a piece of program code woven into the connection point of the target class. Indicates the operation to be performed on the connection point.

Aspect (Aspect)

The aspect is composed of tangent points and enhancements (introduction) (can contain multiple tangent points and multiple enhancements). It includes both the definition of cross-cutting logic and the definition of connection points. SpringAOP is the framework responsible for implementing the aspect. Weave the crosscutting logic defined by the aspect into the link point specified by the aspect.

A good understanding of the concepts of AOP will be of great help to aspect-oriented programming in the future.

 

 

Let's talk about how to use AOP in SpringBoot.

1. Define an aspect

@Aspect//定义一个切面
@Component
@Slf4j
public class SellerAuthorizeAspect {
}

2. Define the aspect

//定义切点,即后面的增强加在指定的切点中,切点是一组连接点的集合,即指定一个范围,
    //这些范围内的连接点就是需要增强的地方
    @Pointcut("execution(public * com.zyh.sell.controller.Seller*.*(..))"
            + "&& !execution(public * com.zyh.sell.controller.SellerUserController.*(..))")
    public void verify() {
    }

 3. Define Advice

//增强的方法,即Advice
    @Before("verify()")
    public void doVerify() {

        //查询cookie中的token
        //得到request对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Cookie cookie = CookieUtil.get(request, Constant.CookieConstant.TOKEN);
        if (cookie == null) {
            log.error("【cookie校验失败】");
            throw new SellerAuthorizeException();
        }
        //查询redis
        String openid = stringRedisTemplate.opsForValue().get(String.format(Constant.RedisConstant.TOKEN_PREFIX, cookie.getValue()));
        if (StringUtils.isEmpty(openid)){
            log.error("【redis校验失败】");
            throw new SellerAuthorizeException();
        }
    }

A complete aspect code:

@Aspect//定义一个切面
@Component
@Slf4j
public class SellerAuthorizeAspect {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    //定义切点,即后面的增强加在指定的切点中,切点是一组连接点的集合,即指定一个范围,
    //这些范围内的连接点就是需要增强的地方
    @Pointcut("execution(public * com.zyh.sell.controller.Seller*.*(..))"
            + "&& !execution(public * com.zyh.sell.controller.SellerUserController.*(..))")
    public void verify() {
    }

    //增强的方法,即Advice
    @Before("verify()")
    public void doVerify() {

        //查询cookie中的token
        //得到request对象
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        Cookie cookie = CookieUtil.get(request, Constant.CookieConstant.TOKEN);
        if (cookie == null) {
            log.error("【cookie校验失败】");
            throw new SellerAuthorizeException();
        }
        //查询redis
        String openid = stringRedisTemplate.opsForValue().get(String.format(Constant.RedisConstant.TOKEN_PREFIX, cookie.getValue()));
        if (StringUtils.isEmpty(openid)){
            log.error("【redis校验失败】");
            throw new SellerAuthorizeException();
        }
    }

}

 6. Controller enhancer @ControllerAdvice

The @ContollerAdvice annotation was added in spring 3.2, which means controller enhancer. The @ControllerAdvice annotation will be applied to all controller methods annotated with @RequestMapping

On the code:

//控制器增强器
@ControllerAdvice
public class SellerExceptionHandler {

    //当控制器发生指定的异常时就会触发指定的方法来增强控制器
    @ExceptionHandler(value = SellerAuthorizeException.class)
    public ModelAndView handleSellerAuthorizeException() {

        return new ModelAndView("redirect:");
    }

}

When the controller throws SellerAuthorizeException, the handleSellerAuthorizeException method is triggered.

 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_37689658/article/details/85215741