​ Identifies a type as being an actuator endpoint that provides information about the running application. Endpoints can be exposed over a variety of technologies including JMX and HTTP.

The Endpoint can provide some information about the Running application, which can be exposed using JMX and HTTP technologies.

The main point is that one is JMX and HTPP technology, and it can provide some information about JAVA processes, so it can be called operations tools

1. Spring customizes the Endpoint

Declared an Endpoint need injection on the Bean org. Springframework. Boot. Actuate. The Endpoint. The annotation. The Endpoint of the annotations, but there is another JmxEndpoint

​ Most @Endpoint classes will declare one or more @ReadOperation, @WriteOperation, @DeleteOperation annotated methods which will be automatically adapted to the exposing technology (JMX, Spring MVC, Spring WebFlux, Jersey etc.).

@Endpoint represents the lowest common denominator for endpoints and intentionally limits the sorts of operation methods that may be defined in order to support the broadest possible range of exposure technologies. If you need deeper support for a specific technology you can either write an endpoint that is filtered to a certain technology, or provide extension for the broader endpoint.

First you need to add dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Copy the code

Next, configure join.

management.endpoints.web.exposure.include=*
management.endpoint.health.show-details=always
Copy the code

The Endpoint class:

@Endpoint(id = "nacos-config")
public class NacosConfigEndpoint {

    private static final Map<String, Object> MAP = new HashMap<>();

	// If the method name is the same as the GET method, it will throw an exception
    @ReadOperation
    public Map<String, Object> get(a) {
        MAP.clear();
        MAP.put("GET"."hello world");
        return MAP;

    }

    // Corresponds to the POST method
    // @selector equals @pathvariable
    @WriteOperation
    public Map<String, Object> post(@Selector String name) {
        MAP.clear();
        MAP.put("POST",name);
        return MAP;
    }

    // corresponds to the DELETE method
    @DeleteOperation
    public Map<String, Object> delete(@Selector String name) {
        MAP.clear();
        MAP.put("DELETE",name);
        returnMAP; }}Copy the code

The configuration class:

@Configuration
public class NacosConfigEndpointAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    public NacosConfigEndpoint nacosEndpoint(a) {
        return newNacosConfigEndpoint(); }}Copy the code

If you start logging, you’ll see that it’s registered,

2019-12-18 17:19:25.497  INFO 5572 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/nacos-config],methods=[GET],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto publicjava.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax .servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)2019-12-18 17:19:25.497  INFO 5572 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/nacos-config/{name}],methods=[DELETE],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto publicjava.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax .servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)2019-12-18 17:19:25.498  INFO 5572 --- [           main] s.b.a.e.w.s.WebMvcEndpointHandlerMapping : Mapped "{[/actuator/nacos-config/{name}],methods=[POST],produces=[application/vnd.spring-boot.actuator.v2+json || application/json]}" onto publicjava.lang.Object org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping$OperationHandler.handle(javax .servlet.http.HttpServletRequest,java.util.Map<java.lang.String, java.lang.String>)Copy the code

And then test the interface

The test results are clearly a match

One last question, what is JMX wow, we used HTTP request above wow, this one is, you can open jConsole tool to see.

2. ControllerEndpoint is more convenient

Org. Springframework. Boot. Actuate. The endpoint. Web. The annotation. ControllerEndpoint we are using the above comments, we don’t know the development is not friendly, this provides, But this one does not provide JMX, so it cannot be managed using JConsole

​ Identifies a type as being an endpoint that is only exposed over Spring MVC or Spring WebFlux. Mapped methods must be annotated with @GetMapping, @PostMapping, @DeleteMapping, etc annotations rather than @ReadOperation, @WriteOperation, @DeleteOperation.

The test class

@ControllerEndpoint(id = "web-mvc", enableByDefault = true)
public class WebMVCControllerEndpoint {

    @ResponseBody
    @GetMapping("/get/{id}")
    public List<String> get(@PathVariable("id") String id) {
        return Arrays.asList("hello ", id, "!"); }}Copy the code

Join the configuration

@Configuration
public class NacosConfigEndpointAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    public NacosConfigEndpoint nacosEndpoint(a) {
        return new NacosConfigEndpoint();
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnEnabledEndpoint
    public WebMVCControllerEndpoint webMVCControllerEndpoint(a) {
        return newWebMVCControllerEndpoint(); }}Copy the code

To start again

2. Java custom JMX

JMX (Java Management Extensions) is a framework for implementing Management capabilities for applications, devices, systems, and so on. JMX allows flexible development of seamlessly integrated system, network and service management applications across a range of heterogeneous operating system platforms, system architectures and network transport protocols.

I simply copied a demo

public interface HelloMBean {

    void echo(String msg);

    String getName(a);

    void setName(String name);
}
Copy the code
/* * The class name must be consistent with the prefix of the implemented interface (that is, the name before the MBean */)
public class Hello implements HelloMBean {

    private String name;

    @Override
    public void echo(String msg) {
        System.out.println("name : " + name + " , echo : " + msg);
    }

    @Override
    public String getName(a) {
        return this.name;
    }

    @Override
    public void setName(String name) {
        this.name = name; }}Copy the code

Start the class

public class HelloAgent {
    public static void main(String[] args) throws JMException, Exception {

        // 1. Get the Mbean Server from the factory class, and use it as a container for mbeans
        MBeanServer server = ManagementFactory.getPlatformMBeanServer();

        // 2. Domain name :name=Mbean name
        ObjectName helloName = new ObjectName("jmxBean:name=hello");

        //2. Register Hello class with MbeanServer and create ObjectName class
        server.registerMBean(newHello(), helloName); System.in.read(); }}Copy the code

Finally, run jConsole with CMD, and since we provide getName and setName methods, you can enter values, but you can’t display values if you don’t provide them in your interface. Or modify the value

We call the echo method, and we can enter parameters into the method

At this point we look at our output:

Is successful call successful, this is JMX, other detailed use on Baidu, basic flow is this