自定義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;
    }
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM