• 【springboot】自定义starter(学习笔记)


    起步依赖

    自动配置

    条件依赖

    Bean参数获取

    Bean的发现

    bean的加载

    总结

    自定义starter案例一:hello-spring-boot-starter

    pom文件

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <parent>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <groupId>org.springframework.bootgroupId>
    9. <version>2.7.2version>
    10. <relativePath/>
    11. parent>
    12. <groupId>com.malguygroupId>
    13. <artifactId>hello-spring-boot-starterartifactId>
    14. <version>1.0-SNAPSHOTversion>
    15. <properties>
    16. <maven.compiler.source>8maven.compiler.source>
    17. <maven.compiler.target>8maven.compiler.target>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starterartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframework.bootgroupId>
    26. <artifactId>spring-boot-autoconfigureartifactId>
    27. dependency>
    28. dependencies>
    29. project>

    配置属性类HelloProperties

    1. import org.springframework.boot.context.properties.ConfigurationProperties;
    2. /**
    3. * 配置属性类,封装配置文件里的信息
    4. * 对应配置文件
    5. * hello:
    6. * name:
    7. * address:
    8. */
    9. @ConfigurationProperties(prefix="hello") //参数的前缀;
    10. public class HelloProperties {
    11. private String name;
    12. private String address;
    13. public String getName() {
    14. return name;
    15. }
    16. public void setName(String name) {
    17. this.name = name;
    18. }
    19. public String getAddress() {
    20. return address;
    21. }
    22. public void setAddress(String address) {
    23. this.address = address;
    24. }
    25. @Override
    26. public String toString() {
    27. return "HelloProperties{" +
    28. "name='" + name + '\'' +
    29. ", address='" + address + '\'' +
    30. '}';
    31. }
    32. }

    服务类(到时boot会自动创建)HelloService

    1. public class HelloService {
    2. private String name;
    3. private String address;
    4. public HelloService(String name, String address) {
    5. this.name = name;
    6. this.address = address;
    7. }
    8. public String sayHello(){
    9. return "你好,my name is "+name+",我 coming from "+address;
    10. }
    11. }

    HelloServiceAutoConfiguration

    1. /**
    2. * 自动配置类,自动配置hello对象
    3. */
    4. @Configuration
    5. @EnableConfigurationProperties(value=HelloProperties.class)
    6. public class HelloServiceAutoConfiguration {
    7. private HelloProperties helloProperties;
    8. //通过构造方法注入配置对象
    9. public HelloServiceAutoConfiguration(HelloProperties helloProperties) {
    10. this.helloProperties = helloProperties;
    11. }
    12. @Bean
    13. @ConditionalOnMissingBean //当没有这个bean的时候才创建
    14. public HelloService helloService(){
    15. return new HelloService(
    16. helloProperties.getName(),
    17. helloProperties.getAddress()
    18. );
    19. }
    20. }

    resources目录下创建META-INF/spring.factories , 可以加载自动配置类

    1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    2. com.malguy.config.HelloServiceAutoConfiguration

    这样就可以install再使用了

    1. "1.0" encoding="UTF-8"?>
    2. <project mlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <parent>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <groupId>org.springframework.bootgroupId>
    9. <version>2.7.2version>
    10. parent>
    11. <groupId>org.examplegroupId>
    12. <artifactId>myappartifactId>
    13. <version>1.0-SNAPSHOTversion>
    14. <properties>
    15. <maven.compiler.source>8maven.compiler.source>
    16. <maven.compiler.target>8maven.compiler.target>
    17. properties>
    18. <dependencies>
    19. <dependency>
    20. <groupId>com.malguygroupId>
    21. <artifactId>hello-spring-boot-starterartifactId>
    22. <version>1.0-SNAPSHOTversion>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframework.bootgroupId>
    26. <artifactId>spring-boot-starter-webartifactId>
    27. dependency>
    28. dependencies>
    29. project>
    1. server:
    2. port:8080
    3. hello:
    4. name: lihua
    5. address: beijing
    1. @RestController
    2. @RequestMapping("/hello")
    3. public class HelloController {
    4. @Autowired
    5. private HelloService helloService;
    6. @GetMapping("/say")
    7. public String sayHello(){
    8. return helloService.sayHello();
    9. }
    10. }
    1. @SpringBootApplication
    2. public class HelloApplication {
    3. public static void main(String[] args) {
    4. SpringApplication.run(HelloApplication.class,args);
    5. }
    6. }

    自定义starter案例二:案例一的基础上添加拦截器,实现记录日志功能

    依赖

    1. "1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0modelVersion>
    6. <parent>
    7. <artifactId>spring-boot-starter-parentartifactId>
    8. <groupId>org.springframework.bootgroupId>
    9. <version>2.7.2version>
    10. <relativePath/>
    11. parent>
    12. <groupId>com.malguygroupId>
    13. <artifactId>hello-spring-boot-starterartifactId>
    14. <version>1.0-SNAPSHOTversion>
    15. <properties>
    16. <maven.compiler.source>8maven.compiler.source>
    17. <maven.compiler.target>8maven.compiler.target>
    18. properties>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.bootgroupId>
    22. <artifactId>spring-boot-starterartifactId>
    23. dependency>
    24. <dependency>
    25. <groupId>org.springframework.bootgroupId>
    26. <artifactId>spring-boot-autoconfigureartifactId>
    27. dependency>
    28. <dependency>
    29. <groupId>org.springframework.bootgroupId>
    30. <artifactId>spring-boot-starter-webartifactId>
    31. dependency>
    32. <dependency>
    33. <groupId>org.springframework.bootgroupId>
    34. <artifactId>spring-boot-configuration-processorartifactId>
    35. dependency>
    36. dependencies>
    37. project>

    自定义MyLog注解

    1. /**
    2. * 自定义日志注解
    3. */
    4. @Target(ElementType.METHOD)//只能加在方法上
    5. @Retention(RetentionPolicy.RUNTIME)//在运行时生效
    6. public @interface MyLog {
    7. /**
    8. * 方法描述
    9. */
    10. String desc() default "";
    11. }

    创建拦截器对象MyLogInterceptor

    1. /**
    2. * 自定义日志拦截器
    3. */
    4. public class MyLogInterceptor extends HandlerInterceptorAdapter {
    5. private static final ThreadLocal startTimeThreadLocal=
    6. new ThreadLocal<>(); //记录时间的毫秒值
    7. //在controller方法执行前执行
    8. @Override
    9. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    10. HandlerMethod handlerMethod = (HandlerMethod) handler;
    11. Method method = handlerMethod.getMethod();//获取当前拦截到的方法
    12. MyLog myLog = method.getAnnotation(MyLog.class);//方法上获取mylog注解
    13. if(myLog!=null){
    14. //当前拦截的方法上加了MyLog注解
    15. long startTime = System.currentTimeMillis();//获取当前时间(毫秒)
    16. startTimeThreadLocal.set(startTime);
    17. }
    18. return true;
    19. }
    20. //在controller方法执行后执行
    21. @Override
    22. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    23. HandlerMethod handlerMethod = (HandlerMethod) handler;
    24. Method method = handlerMethod.getMethod();//获取当前拦截到的方法
    25. MyLog myLog = method.getAnnotation(MyLog.class);//方法上获取mylog注解
    26. if(myLog!=null){
    27. //当前拦截的方法上加了MyLog注解
    28. Long startTime = startTimeThreadLocal.get();
    29. long endTime = System.currentTimeMillis();//获取当前时间(毫秒)
    30. long optTime=endTime-startTime;//计算controller方法执行时间
    31. String requestUri= request.getRequestURI();
    32. String methodName=method.getDeclaringClass().getName()+"."+
    33. method.getName();
    34. String methodDesc=myLog.desc();
    35. System.out.println("请求uri: "+requestUri);
    36. System.out.println("请求方法名: "+methodName);
    37. System.out.println("方法描述: "+methodDesc);
    38. System.out.println("方法执行时间: "+optTime+"ms");
    39. }
    40. super.postHandle(request, response, handler, modelAndView);
    41. }
    42. }

    自动配置类自动实例化拦截器对象(注册为bean)

    1. @Configuration
    2. public class MyLogAutoConfiguration implements WebMvcConfigurer {
    3. //注册自定义日志拦截器
    4. @Override
    5. public void addInterceptors(InterceptorRegistry registry) {
    6. registry.addInterceptor(new MyLogInterceptor());
    7. }
    8. }

    spring.factories

    1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    2. com.malguy.config.HelloServiceAutoConfiguration,\
    3. com.malguy.config.MyLogAutoConfiguration

    重新打包install,在myapp的controller方法上加注解,测试

    1. @RestController
    2. @RequestMapping("/hello")
    3. public class HelloController {
    4. @Autowired
    5. private HelloService helloService;
    6. @GetMapping("/say")
    7. @MyLog(desc="sayHello方法")
    8. public String sayHello(){
    9. return helloService.sayHello();
    10. }
    11. }

  • 相关阅读:
    C++ - Java 调用 C++ 动态库 <.dylib / .so> By CLion
    盲盒小程序预售机制的设计与实施
    static const与static constexpr的类内数据成员初始化
    【赠书活动】无测试组织:测试团队的敏捷转型
    基于Matlab+ AlexNet神经网络的动物识别系统
    小红书种草步骤:小红书种草怎么做?
    FFmpeg获取媒体文件的音频信息
    安卓APT技术讲解(下)-实现安卓组件化的路由功能
    Jvm与DVM与ART
    国民经济行业代码查询系统-公司行业代码查询
  • 原文地址:https://blog.csdn.net/m0_60707623/article/details/126654442