概述
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主要帮助我们做了两件事。
- 获取到使用@ConfigurationProperties的类;
- 解析配置文件,将对应的值设置到我们的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自动注入属性如何实现自动配置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复