我是靠谱客的博主 拼搏萝莉,最近开发中收集的这篇文章主要介绍Mybatis-plus自动注入属性如何实现自动配置,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Mybatis-plus属性自动填充配置

  • 如何实现自动配置
    • 使用@ConfigurationProperties
      • @ConfigurationProperties实现原理
      • 手写代码
    • 注册MetaObjectHandler
    • 扩展知识
      • @FieldNameConstants
        • 一、注解介绍
        • 二、属性介绍(非必选)

如何实现自动配置

使用@ConfigurationProperties

@ConfigurationProperties是springboot提供读取配置文件的一个注解。其对应的bean的后置处理器是ConfigurationPropertiesBingingPostProcessor,在bean被实例化后,会调用后置处理,递归的查找属性,通过反射注入值,对大多数属性而言强制需提供其setter和getter方法。

使用prefix属性可以实现配置文件的自动注入

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
@Component
@ConfigurationProperties(prefix = "config")
public class TestBean{
 
    private String username;
    
    private String password;
}

@ConfigurationProperties实现原理

SpringBoot如何获取到它的值呢?通过源码发现,SpringBoot主要帮助我们做了两件事。

  1. 获取到使用@ConfigurationProperties的类;
  2. 解析配置文件,将对应的值设置到我们的Bean中

按照源码实现思路,核心就是对Bean的声明周期的管理。主要涉及BeanPostProcessor的接口。下面的两个方法,主要事在Spring的Bean初始化前后执行

public interface BeanPostProcessor {
 
    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
 
    
    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
 
}

手写代码

第一步,定义注解。这个注解最后实现的功能希望与@ConfiguratioonProperties类似

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Config {
 
    /**
     * 配置属性 的前缀
     */
    String prefix();
}

第二步,定义配置测试实体

import lombok.Data;
import org.springframework.stereotype.Component;
 
@Config(prefix = "default")
@Component
@Data
public class TestDataSource {
 
    private String username;
 
    private String password;
 
    private int maxActiveCount;
}

第三步,编写配置文件

default.username = root
default.password = 3333
default.maxActiveCount = 10
default.maxActiveCount2 = 10

第四步,编写处理逻辑
1.获取使用了自定义注解的@Config类
2.解析配置文件,并将对应的值使用反射技术,注入到Bean中

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
 
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;
 
@Component
public class ConfigPostProcess implements BeanPostProcessor {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(ConfigPostProcess.class);
 
    private static final String FILE_NAME = "config.properties";
 
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //获取使用了我们自定义注解@Config的类
        Config configAnnotation = AnnotationUtils.findAnnotation(bean.getClass(), Config.class);
        //如果这个对象使用了此注解
        if (configAnnotation != null) {
            LOGGER.info("当前操作的类:{}", beanName);
            //解析配置文件,并将解析结果放入Map中
            Map<String, String> configProperties = getConfigPropertiesFromFile(configAnnotation);
            //将对应的值,使用反射技术,注入到这个bean中
            bindBeanValue(bean, configProperties);
        }
 
        return bean;
    }
  ...
}

注册MetaObjectHandler

注册MetaObjectHandler,并实现insertFill和updateFill方法

BaseEntity实现@FiledNameConstants

@FiledNameConstants
public class BaseEntity implements Serializable{
		@TableId
		private Long id;

		@TableField(fill = FieldFill.INSERT)
		private String creator;

		@TableField(fill = FieldFill.INSERT)
		private Date createDate;

		@TableField(fill = FieldFill.INSERT_UPDATE)
		private String modifier;

		@TableField(fill = FieldFill.INSERT_UPDATE)
		private Date modifiedDate;

		@TableField(fill = FIledFill.INSERT)
		private String isDeleted;
}
@Bean
public MetaObjectHandler metaObjectHandler(){
	return new MetaObjectHandler(){
		@Overwrite
		public void insertFill(MetaObject metaObject){
			//设置逻辑删除为N
			strictInsertFill(metaObject,"isDeleted",String.class,'N');
			//获取用户信息
			//如果用户信息不为空
			metaObject.setValue(BaseEntity.Fields.creator,用户id);
			//如果用户信息为空
			metaObject.setValue(BaseEntity.Fields.creator,"test")
			//设置创建时间、修改时间、修改人
			metaObject.setValue(BaseEntity.Fields.creatDate,new Date());
			metaObject.setValue(BaseEntity.Fields.modifiedDate,new Date());
			metaObject.setValue(BaseEntity.Fields.modifier,metaObject.getValue(BaseEntity.Fields.creator));
			
		}
	}

	@Overwrite
	public void updateFill(MetaObject metaObject){
		//如果获取到了登录人信息
		metaObject.setValue(BaseEntity.Fields.modifier,登录人id);
		//如果没有获取到登录人信息
		metaObject.setValue(BaseEntity.Fileds.modifier,"test");
		//设置修改时间
		metaObject.setValue(BaseEntity.Fields.modifiedDate,new Date());
		
	}
}

扩展知识

@FieldNameConstants

一、注解介绍

作用于类,生成一个包含所有成员变量的内部类或内部枚举,内部类中每个字段值即为字段名称,且内部类字段不可变

二、属性介绍(非必选)

  • value:设置内部类或者枚举的控制符,默认为public,共有PUBLIC、MODULE、PROTECTED、PACKAGE、PRIVATE、NONE MODULE,NONE 表示不生成setter方法
  • asEnum:是否为枚举类型(控制生成内部类还是内部枚举)
  • innerTypeName:设置内部类或枚举名,默认值:“”,默认内部类名:Fields
  • onlyExplicitlyIncluded:仅包含标记为@ToString.include的字段,默认为false
  • Include:设置包含哪些字段
    Include只有在onlyExplicitlyIncluded=true时才会生效,Include标记在需要包含的属性或方法上
  • Exclude:设置不包含哪些字段

最后

以上就是拼搏萝莉为你收集整理的Mybatis-plus自动注入属性如何实现自动配置的全部内容,希望文章能够帮你解决Mybatis-plus自动注入属性如何实现自动配置所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(102)

评论列表共有 0 条评论

立即
投稿
返回
顶部