• 自定义Spring-Boot @Enable注解


    Spring-Boot中有很多Enable开头的注解,通过添加注解来开启一项功能,如

    其原理是什么?如何开发自己的Enable注解?

    1.原理

    以@EnableScheduling为例,查看其源码,发现添加了一个@Import注解

    继续查看@Import注解源码,发现其是由Spring提供的,用来导入配置类的,在配置类中定义的Bean(@Bean),可通过@Autowired注入到容器中,也就是可以被扫描到

    2.自定义

    了解了Enable注解的原理,我们就可以开发自己的Enable注解了,下面的例子实现了通过@Enable注解方式开启服务器负载监控的功能

    2.1 定义定时任务类

    package com.yc.dudu.common.monitor;
    
    import com.alibaba.fastjson.JSONObject;
    import com.sun.management.OperatingSystemMXBean;
    import com.yc.dudu.common.constant.CommonConstants;
    import com.yc.dudu.common.util.DateTimeUtil;
    import com.yc.dudu.common.vo.ServerMonitorInfo;
    import lombok.extern.slf4j.Slf4j;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.scheduling.annotation.EnableScheduling;
    import org.springframework.scheduling.annotation.Scheduled;
    
    import java.io.File;
    import java.lang.management.ManagementFactory;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    /**
     * 收集服务器负载信息
     *
     * @author zhya
     * @date 2018/9/20
     **/
    @Slf4j
    @EnableScheduling
    public class ServerLoadMonitorRunner implements CommandLineRunner {
        /**
         * 自定义log,输出服务器负载信息到日志文件
         */
        private static final Logger monitorLog = LoggerFactory.getLogger("serverMonitorLog");
    
        /**
         * 系统信息
         */
        private static final OperatingSystemMXBean mem = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
    
        /**
         * 收集服务器负载信息并输出到日志文件
         */
        @Scheduled(cron = "*/5 * * * * ?")
        public void collectServerSystemLoad() {
            try {
                // 输出json格式的信息到文件
                monitorLog.info(JSONObject.toJSONString(new ServerMonitorInfo(InetAddress.getLocalHost().getHostName(),
                        String.valueOf(mem.getFreePhysicalMemorySize() / CommonConstants.BYTES_TO_MB),
                        String.valueOf(mem.getSystemCpuLoad()),
                        String.valueOf(File.listRoots()[0].getFreeSpace() / CommonConstants.BYTES_TO_MB),
                        DateTimeUtil.getNowDateTimeStr())));
            } catch (UnknownHostException e) {
                log.error(e.getMessage());
            }
        }
    
        /**
         * Callback used to run the bean.
         *
         * @param args incoming main method arguments
         * @throws Exception on error
         */
        @Override
        public void run(String... args) throws Exception {
            try {
                collectServerSystemLoad();
            } catch (Exception e) {
                log.error(e.getMessage());
                // 不做处理,继续运行
            }
        }
    }
    

      

     2.2 定义配置类,其中声明定时任务Bean

    package com.yc.dudu.common.monitor;
    
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.PostConstruct;
    
    /**
     * 服务器负载监控自动配置类
     *
     * @author zhya
     * @date 2018/09/20
     **/
    @Configuration
    public class ServerLoadMonitorAutoConfig {
        /**
         * 是否开启监控配置参数
         */
        @Value("${monitor.server.enabled:}")
        private String enabledConfig;
    
        /**
         * 错误提醒
         */
        @PostConstruct
        protected void init() {
            if (StringUtils.isBlank(enabledConfig)) {
                System.err.println("~~~Please config the monitor.server.enabled property in application.yml file to enable server monitor function~~~");
            }
        }
    
        /**
         * 根据运行环境决定是否开启服务器负载信息监控
         *
         * @return
         */
        @Bean
        @ConditionalOnProperty(prefix = "monitor.server", name = "enabled", havingValue = "true")
        protected ServerLoadMonitorRunner startServerMonitor() {
            return new ServerLoadMonitorRunner();
        }
    }
    

    2.3 定义自己的Enable注解,Import 配置类

    package com.yc.dudu.common.monitor;
    
    import org.springframework.context.annotation.Import;
    
    import java.lang.annotation.*;
    
    /**
     * 服务器负载监控开启注解
     *
     * @author zhya
     * @date 2018/09/20
     **/
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Import(ServerLoadMonitorAutoConfig.class)
    @Documented
    @Inherited
    public @interface EnableServerLoadMonitor {
    }
    

    2.4 使用自定义的EnableServerLoadMonitor注解,配合着配置参数,就可以开启服务器负载监控功能了

    package com.yc.dudu.gate.admin;
    
    import com.yc.dudu.auth.client.EnableDuduAuthClient;
    import com.yc.dudu.common.monitor.EnableServerLoadMonitor;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.hystrix.EnableHystrix;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.annotation.Bean;
    import zipkin2.Span;
    import zipkin2.reporter.Reporter;
    
    /**
     * admin网关启动类
     *
     * @author zhya
     * @date 2018/9/20
     **/
    @EnableHystrix
    @EnableServerLoadMonitor
    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableDuduAuthClient
    @EnableFeignClients({"com.yc.dudu.auth.client.feign", "com.yc.dudu.gate.admin.feign"})
    public class AdminGatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(AdminGatewayApplication.class, args);
            System.out.println("AdminGatewayApplication is started!~~~~~~~~");
        }
    
        /**
         * 链路跟踪信息输出log
         */
        private static Logger sleuthLog = LoggerFactory.getLogger("sleuthLog");
    
        /**
         * 将链路跟踪信息输出到日志文件
         *
         * @return
         */
        @Bean
        public Reporter<Span> spanReporter() {
            Reporter<Span> reporter = span -> sleuthLog.info(span.toString());
            return reporter;
        }
    }
    

      

  • 相关阅读:
    ubuntu上virtualbox无法找到usb设备【解决】
    try or install Ubuntu on MeegoPad T01
    213. 打家劫舍 II
    198. 打家劫舍
    70. 爬楼梯
    62. 不同路径
    idea | gitee 码云
    数据库 | 远程连接centos7上数据库
    JSP && Servlet | 上传图片到数据库
    bootstrap | 模态框
  • 原文地址:https://www.cnblogs.com/zhya/p/9847972.html
Copyright © 2020-2023  润新知