戴尔集群监控与管理系统_监控与管理

戴尔集群监控与管理系统

本文是我们名为“ EAI的Spring集成 ”的学院课程的一部分。

在本课程中,向您介绍了企业应用程序集成模式以及Spring Integration如何解决它们。 接下来,您将深入研究Spring Integration的基础知识,例如通道,转换器和适配器。 在这里查看 !

目录

1.简介 2.发布和接收JMX通知
2.1。 发布JMX通知 2.2。 接收JMX通知
3.从MBean轮询托管属性 4.调用MBean操作 5.将组件导出为MBean 6.跟踪消息路径 7.保留缓冲的消息 8.实现幂等组件 9.发送操作调用请求

1.简介

在尝试了Spring Integration提供的主要组件并了解了它如何与JMS队列或Web服务之类的其他系统很好地集成之后,本章通过展示不同的监视或收集有关消息传递中发生的情况的机制来结束本课程。系统。

其中一些机制包括通过MBean管理或监视应用程序,MBean是JMX规范的一部分。 我们还将学习如何监视消息以查看消息传递流程中涉及哪些组件,以及如何为具有缓冲消息能力的组件保留消息。

本章讨论的另一种机制是我们将如何使用元数据存储实现EIP幂等接收器模式。

最后,描述的最后一种机制是控制总线。 这将使我们发送消息,这些消息将调用应用程序上下文中的组件上的操作。

2.发布和接收JMX通知

JMX规范定义了一种机制,该机制允许MBean发布将发送到其他MBean或管理应用程序的通知。 Oracle 文档解释了如何实现此机制。

Spring Integration通过提供能够发布和接收JMX通知的通道适配器来支持此功能。 我们将看到一个使用两个通道适配器的示例:

  • 通知监听通道适配器
  • 通知发布通道适配器

发布JMX通知

在示例的第一部分中,消息传递系统通过其入口网关接收String消息(具有有效载荷类型为String的消息)。 然后,它使用服务激活器(通知处理程序)来构建javax.management.Notification并将其发送到通知发布通道适配器,该适配器将发布JMX通知。

第一部分的流程如下所示:

图1

图1

xml配置等同于上图:

<context:component-scan base-package="xpadro.spring.integration.jmx.notification"/><context:mbean-export/>
<context:mbean-server/><!-- Sending Notifications -->
<int:gateway service-interface="xpadro.spring.integration.jmx.notification.JmxNotificationGateway" default-request-channel="entryChannel"/><int:channel id="entryChannel"/><int:service-activator input-channel="entryChannel" output-channel="sendNotificationChannel" ref="notificationHandler" method="buildNotification"/><int:channel id="sendNotificationChannel"/><int-jmx:notification-publishing-channel-adapter channel="sendNotificationChannel" object-name="xpadro.spring.integration.jmx.adapter:type=integrationMBean,name=integrationMbean"/>

网关与前面的示例一样简单。 请记住,如果只有一种方法,则@Gateway注释不是必需的:

public interface JmxNotificationGateway {public void send(String type);
}

Message将到达服务激活器,该服务激活器将使用JMX通知构建消息:

@Component("notificationHandler")
public class NotificationHandler {private Logger logger = LoggerFactory.getLogger(this.getClass());private static final String NOTIFICATION_TYPE_HEADER = "jmx_notificationType";public void receive(Message<Notification> msg) {logger.info("Notification received: {}", msg.getPayload().getType());}public Message<Notification> buildNotification(Message<String> msg) {Notification notification = new Notification(msg.getPayload(), this, 0);return MessageBuilder.withPayload(notification).copyHeadersIfAbsent(msg.getHeaders()).setHeader(NOTIFICATION_TYPE_HEADER, "myJmxNotification").build();}
}

注意,我们已经设置了一个新的标题。 这对于提供通知类型是必需的,否则JMX适配器将抛出IllegalArgumentException并显示消息“没有可用的通知类型头,并且没有提供默认值”。

最后,我们只需要返回消息即可发送到发布适配器。 其余的由Spring Integration处理。

接收JMX通知

该流程的第二部分包含一个通知侦听通道适配器,它将接收我们先前发布的通知。

图2

图2

xml配置:

<!-- Receiving Notifications -->
<int-jmx:notification-listening-channel-adapter channel="receiveNotificationChannel" object-name="xpadro.spring.integration.jmx.adapter:type=integrationMBean,name=integrationMbean"/><int:channel id="receiveNotificationChannel"/><int:service-activator input-channel="receiveNotificationChannel" ref="notificationHandler" method="receive"/>

我们将只收到通知并记录它:

public void receive(Message<Notification> msg) {logger.info("Notification received: {}", msg.getPayload().getType());
}

运行示例的应用程序:

public class NotificationApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/jmx/config/int-notification-config.xml");JmxNotificationGateway gateway = context.getBean(JmxNotificationGateway.class);gateway.send("gatewayNotification");Thread.sleep(1000);context.close();}
}

3.从MBean轮询托管属性

假设我们有一个正在监视某些功能的MBean 。 使用属性轮询通道适配器,您的应用程序将能够轮询MBean并接收更新的数据。

我实现了一个MBean ,每次询问时都会生成一个随机数。 这不是最重要的功能,但可以为我们提供示例:

@Component("pollingMbean")
@ManagedResource
public class JmxPollingMBean {@ManagedAttributepublic int getNumber() {Random rnd = new Random();int randomNum = rnd.nextInt(100);return randomNum;}
}

流程再简单不过了; 我们需要一个属性轮询通道适配器,用于指定MBean的类型和名称。 适配器将轮询MBean并将结果放置在结果通道中。 轮询的每个结果将通过流标准输出通道适配器显示在控制台上:

<context:component-scan base-package="xpadro.spring.integration.jmx.polling"/><context:mbean-export/>
<context:mbean-server/><!-- Polling -->
<int-jmx:attribute-polling-channel-adapter channel="resultChannel"object-name="xpadro.spring.integration.jmx.polling:type=JmxPollingMBean,name=pollingMbean"attribute-name="Number"><int:poller max-messages-per-poll="1" fixed-delay="1000"/>
</int-jmx:attribute-polling-channel-adapter><int:channel id="resultChannel"/><int-stream:stdout-channel-adapter channel="resultChannel" append-newline="true"/>

运行示例的应用程序:

public class PollingApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/jmx/config/int-polling-config.xml");context.registerShutdownHook();Thread.sleep(5000);context.close();}
}

和控制台输出:

2014-04-16 16:23:43,867|AbstractEndpoint|started org.springframework.integration.config.ConsumerEndpointFactoryBean#0
82
72
20
47
21
2014-04-16 16:23:48,878|AbstractApplicationContext|Closing org.springframework.context.support.ClassPathXmlApplicationContext@7283922

4.调用MBean操作

下一个机制允许我们调用MBean的操作。 我们将实现另一个包含单个操作的bean,我们的老朋友hello world:

@Component("operationMbean")
@ManagedResource
public class JmxOperationMBean {@ManagedOperationpublic String hello(String name) {return "Hello " + name;}
}

现在,如果操作未返回结果,则可以使用通道适配器,或者如果网关不返回结果,则可以使用网关。 通过以下xml配置,我们导出MBean并使用网关来调用操作并等待结果:

<context:component-scan base-package="xpadro.spring.integration.jmx.operation"/><context:mbean-export/>
<context:mbean-server/><int:gateway service-interface="xpadro.spring.integration.jmx.operation.JmxOperationGateway" default-request-channel="entryChannel"/><int-jmx:operation-invoking-outbound-gateway request-channel="entryChannel" reply-channel="replyChannel"object-name="xpadro.spring.integration.jmx.operation:type=JmxOperationMBean,name=operationMbean" operation-name="hello"/><int:channel id="replyChannel"/><int-stream:stdout-channel-adapter channel="replyChannel" append-newline="true"/>

为了工作,我们必须指定MBean的类型和名称以及我们要调用的操作。 结果将被发送到流通道适配器,以便在控制台上显示。

运行示例的应用程序:

public class OperationApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/jmx/config/int-operation-config.xml");JmxOperationGateway gateway = context.getBean(JmxOperationGateway.class);gateway.hello("World");Thread.sleep(1000);context.close();}
}

5.将组件导出为MBean

此组件用于将消息通道,消息处理程序和消息端点导出为MBean,以便您可以对其进行监视。

您需要将以下配置放入您的应用程序:

<int-jmx:mbean-export id="integrationMBeanExporter"default-domain="xpadro.integration.exporter" server="mbeanServer"/><bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"><property name="locateExistingServerIfPossible" value="true"/>
</bean>

并按照Spring 文档中的说明设置以下VM参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6969
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false

运行该示例的应用程序将发送三则消息:

public class ExporterApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/jmx/config/int-exporter-config.xml");context.registerShutdownHook();JmxExporterGateway gateway = context.getBean(JmxExporterGateway.class);gateway.sendMessage("message 1");Thread.sleep(500);gateway.sendMessage("message 2");Thread.sleep(500);gateway.sendMessage("message 3");}
}

应用程序运行后,您可以查看有关组件的信息。 以下屏幕快照是在JConsole上制作的:

图3

图3

您会注意到,输入通道的sendCount属性值为3,因为在本示例中,我们已发送了3条消息。

6.跟踪消息路径

在消息传递系统中,组件是松散耦合的。 这意味着发送组件不需要知道谁将接收消息。 反之,接收者只对接收到的消息感兴趣,而不是谁发送消息。 当我们需要调试应用程序时,这种好处可能不是很好。

消息历史记录包括在消息上附加消息传递的所有组件的列表。

以下应用程序将通过多个组件发送消息来测试此功能:

图4

图4

该配置的关键元素在上图中不可见: message-history元素:

<context:component-scan base-package="xpadro.spring.integration.msg.history"/><int:message-history/><int:gateway id="historyGateway" service-interface="xpadro.spring.integration.msg.history.HistoryGateway" default-request-channel="entryChannel"/><int:channel id="entryChannel"/><int:transformer id="msgTransformer" input-channel="entryChannel" expression="payload + 'transformed'" output-channel="transformedChannel"/><int:channel id="transformedChannel"/><int:service-activator input-channel="transformedChannel" ref="historyActivator"/>

使用此配置集,消息流结尾的服务激活器将能够通过查看消息的标头来检索已访问组件的列表:

@Component("historyActivator")
public class HistoryActivator {private Logger logger = LoggerFactory.getLogger(this.getClass());public void handle(Message<String> msg) {MessageHistory msgHistory = msg.getHeaders().get(MessageHistory.HEADER_NAME, MessageHistory.class);if (msgHistory != null) {logger.info("Components visited: {}", msgHistory.toString());}}
}

运行此示例的应用程序:

public class MsgHistoryApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/msg/history/config/int-msg-history-config.xml");HistoryGateway gateway = context.getBean(HistoryGateway.class);gateway.send("myTest");Thread.sleep(1000);context.close();}
}

结果将显示在控制台上:

2014-04-16 17:34:52,551|HistoryActivator|Components visited: historyGateway,entryChannel,msgTransformer,transformedChannel

7.保留缓冲的消息

Spring Integration中的某些组件可以缓冲消息。 例如,队列通道将缓冲消息,直到使用者从中检索消息为止。 另一个示例是聚合器端点; 如第二个教程中所见,此终结点将根据组的发布策略来收集消息,直到组完成为止。

这些集成模式意味着,如果发生故障,则缓冲的消息可能会丢失。 为了防止这种情况,我们可以保留这些消息,例如将它们存储到数据库中。 默认情况下,Spring Integration将这些消息存储在内存中。 我们将使用消息存储来更改此设置。

对于我们的示例,我们将这些消息存储到MongoDB数据库中。 为此,我们只需要以下配置:

<bean id="mongoDbFactory" class="org.springframework.data.mongodb.core.SimpleMongoDbFactory"><constructor-arg><bean class="com.mongodb.Mongo"/></constructor-arg><constructor-arg value="jcgdb"/>
</bean><bean id="mongoDbMessageStore" class="org.springframework.integration.mongodb.store.ConfigurableMongoDbMessageStore"><constructor-arg ref="mongoDbFactory"/>
</bean>

现在,我们将创建一个应用程序来测试此功能。 我实现了一个通过网关接收带有String有效负载的消息的流。 网关将该消息发送到队列通道,该通道将缓冲消息,直到服务激活程序msgStoreActivator从队列中检索到该消息为止。 服务激活器将每五秒钟轮询一次消息:

<context:component-scan base-package="xpadro.spring.integration.msg.store"/><import resource="mongodb-config.xml"/><int:gateway id="storeGateway" service-interface="xpadro.spring.integration.msg.store.MsgStoreGateway" default-request-channel="entryChannel"/><int:channel id="entryChannel"><int:queue message-store="myMessageStore"/>
</int:channel><int:service-activator input-channel="entryChannel" ref="msgStoreActivator"><int:poller fixed-rate="5000"/>
</int:service-activator>

也许您已经注意到myMessageStore bean。 为了查看持久消息机制的工作方式,我扩展了ConfigurableMongoDBMessageStore类以将日志放入其中并调试结果。 如果要尝试此操作,可以删除mongodb-config.xml的MongoDB messageStore bean,因为我们不再使用它。

我已经覆盖了两种方法:

@Component("myMessageStore")
public class MyMessageStore extends ConfigurableMongoDbMessageStore {private Logger logger = LoggerFactory.getLogger(this.getClass());private static final String STORE_COLLECTION_NAME = "messageStoreCollection";@Autowiredpublic MyMessageStore(MongoDbFactory mongoDbFactory) {super(mongoDbFactory, STORE_COLLECTION_NAME);logger.info("Creating message store '{}'", STORE_COLLECTION_NAME);}@Overridepublic MessageGroup addMessageToGroup(Object groupId, Message<?> message) {logger.info("Adding message '{}' to group '{}'", message.getPayload(), groupId);return super.addMessageToGroup(groupId, message);}@Overridepublic Message<?> pollMessageFromGroup(Object groupId) {Message<?> msg = super.pollMessageFromGroup(groupId);if (msg != null) {logger.info("polling message '{}' from group '{}'", msg.getPayload(), groupId);}else {logger.info("Polling null message from group {}", groupId);}return msg;}
}

该机制的工作原理如下:

  1. 当一条消息到达配置了我们的消息存储的队列通道时,它将调用“ addMessageToGroup”方法。 此方法会将带有有效负载的文档插入构造函数中指定的MongoDB集合。 这是通过使用MongoTemplate完成的。
  2. 当使用者轮询消息时,将调用pollMessageFromGroup ,从集合中检索文档。

让我们通过调试代码来看看它是如何工作的。 我们将在轮询消息以查看其在数据库中的存储方式之前停止:

图5

图5

现在,我们可以看一下数据库:

图6

图6

恢复后,将从集合中轮询消息:

图7

图7

运行示例的应用程序:

public class MsgStoreApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/msg/store/config/int-msg-store-config.xml");MsgStoreGateway gateway = context.getBean(MsgStoreGateway.class);gateway.send("myMessage");Thread.sleep(30000);context.close();}
}

8.实现幂等组件

如果我们的应用程序需要避免重复消息,Spring Integration通过实现幂等接收器模式来提供此机制。 负责检测重复消息的是元数据存储组件。 该组件包括存储键值对。 该框架提供了接口MetadataStore两种实现:

  • SimpleMetadataStore :默认实现。 它使用内存映射来存储信息。
  • PropertiesPersistingMetadataStore :如果需要持久化数据,则很有用。 它使用属性文件。 我们将在示例中使用此实现。

好的,让我们从配置文件开始:

<context:component-scan base-package="xpadro.spring.integration.msg.metadata"/><bean id="metadataStore"
class="org.springframework.integration.metadata.PropertiesPersistingMetadataStore"/><int:gateway id="metadataGateway" service-interface="xpadro.spring.integration.msg.metadata.MetadataGateway"default-request-channel="entryChannel"/><int:channel id="entryChannel"/><int:filter input-channel="entryChannel" output-channel="processChannel"discard-channel="discardChannel" expression="@metadataStore.get(headers.messageId) == null"/><!-- Process message -->            
<int:publish-subscribe-channel id="processChannel"/><int:outbound-channel-adapter channel="processChannel" expression="@metadataStore.put(headers.messageId, '')"/><int:service-activator input-channel="processChannel" ref="metadataActivator" method="process"/><!-- Duplicated message - discard it -->
<int:channel id="discardChannel"/><int:service-activator input-channel="discardChannel" ref="metadataActivator" method="discard"/>

我们定义了一个“ metadataStore”,以便使用我们的属性元数据存储来代替默认的内存实现。

流程说明如下:

  1. 一条消息发送到网关。
  2. 由于它是第一次发送,因此过滤器会将消息发送到过程通道。
  3. 处理通道有两个订阅者:处理消息的服务激活器和出站通道适配器。 通道适配器会将消息标头messagId的值发送到元数据存储。
  4. 元数据存储将值存储在属性文件中。
  5. 下次发送相同的消息; 过滤器将找到该值并丢弃该消息。

元数据存储在文件系统中创建属性文件。 如果您使用Windows,则会在“ C:\ Users \用户名\ AppData \ Local \ Temp \ spring-integration”文件夹中看到一个meta-store.properties文件

该示例使用服务激活器来记录是否已处理消息:

@Component("metadataActivator")
public class MetadataActivator {private Logger logger = LoggerFactory.getLogger(this.getClass());public void process(Message<String> msg) {logger.info("Message processed: {}", msg.getPayload());}public void discard(Message<String> msg) {logger.info("Message discarded: {}", msg.getPayload());}
}

该应用程序将运行示例:

public class MetadataApp {private static final String MESSAGE_STORE_HEADER = "messageId";public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/msg/metadata/config/int-msg-metadata-config.xml");MetadataGateway gateway = context.getBean(MetadataGateway.class);Map<String,String> headers = new HashMap<>();headers.put(MESSAGE_STORE_HEADER, "msg1");Message<String> msg1 = MessageBuilder.withPayload("msg1").copyHeaders(headers).build();headers = new HashMap<>();headers.put(MESSAGE_STORE_HEADER, "msg2");Message<String> msg2 = MessageBuilder.withPayload("msg2").copyHeaders(headers).build();gateway.sendMessage(msg1);Thread.sleep(500);gateway.sendMessage(msg1);Thread.sleep(500);gateway.sendMessage(msg2);Thread.sleep(3000);context.close();}
}

第一次调用将在控制台上产生以下输出:

2014-04-17 13:00:08,223|MetadataActivator|Message processed: msg1
2014-04-17 13:00:08,726|MetadataActivator|Message discarded: msg1
2014-04-17 13:00:09,229|MetadataActivator|Message processed: msg2

现在请记住,PropertiesPersistingMetadataStore将数据存储在属性文件中。 这意味着该数据将在ApplicationContext重新启动后继续存在。 因此,如果我们不删除属性文件,而是再次运行示例,结果将有所不同:

2014-04-17 13:02:27,117|MetadataActivator|Message discarded: msg1
2014-04-17 13:02:27,620|MetadataActivator|Message discarded: msg1
2014-04-17 13:02:28,123|MetadataActivator|Message discarded: msg2

9.发送操作调用请求

本教程讨论的最后一种机制是控制总线 。 控制总线将使您以与应用程序相同的方式管理系统。 该消息将作为一种Spring Expression Language执行。 若要从控制总线执行,该方法需要使用@ManagedAttribute或@ManagedOperation批注。

本节的示例使用控制总线来调用Bean上的方法:

<context:component-scan base-package="xpadro.spring.integration.control.bus"/><int:channel id="entryChannel"/><int:control-bus input-channel="entryChannel" output-channel="resultChannel"/><int:channel id="resultChannel"/><int:service-activator input-channel="resultChannel" ref="controlbusActivator"/>

将被调用的操作如下:

@Component("controlbusBean")
public class ControlBusBean {@ManagedOperationpublic String greet(String name) {return "Hello " + name;}
}

运行该示例的应用程序发送一条消息,其中包含要执行的表达式:

public class ControlBusApp {public static void main(String[] args) throws InterruptedException {AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:xpadro/spring/integration/control/bus/config/int-control-bus-config.xml");MessageChannel channel = context.getBean("entryChannel", MessageChannel.class);Message<String> msg = MessageBuilder.withPayload("@controlbusBean.greet('World!')").build();channel.send(msg);Thread.sleep(3000);context.close();}
}

结果显示在控制台上:

2014-04-17 13:21:42,910|ControlBusActivator|Message received: Hello World!

翻译自: https://www.javacodegeeks.com/2015/09/monitoring-and-management.html

戴尔集群监控与管理系统

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/336968.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三位数除以两位数竖式计算没有余数_苏教四上期末复习——两、三位数除以两位数...

期末复习读万卷书 &#xff1c;做一好题第二单元两、三位数除以两位数计算能力1、竖式计算5106740961700262914246829810132、简便方法计算150253810(92)560353、填空720秒( )分300分( )时336时( )日调商1、小李计算一道除法是两位数的除法算式&#xff0c;商是12&#x…

单例模式示例_单例设计模式示例

单例模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

解读C++即将迎来的重大更新(一):C++20的四大新特性

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络C20&#xff08;C 编程语言标准 2020 版&#xff09;将是 C 语言一次非常重大的更新&#xff0c;将为这门语言引入大量新特性。…

小尼机器人_小尼被机器人嫌弃“唱歌难听,长相一般”?

我们如今所处的时代&#xff0c;科技创新的速度日新月异,生活方式多彩多姿。人人都说&#xff1a;科技改变了生活。今晚《开门大吉》也迎来了三大改变生活的神奇黑科技&#xff01;智能且生态的“移动城堡”在网上预定好酒店以后&#xff0c;到了现场没有前台和服务员&#xff…

产品原型示例_原型设计模式示例

产品原型示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

13 年,MySQL 之父赌赢了:另起炉灶的 MariaDB 成功上市!

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络&#xff0c;侵权删&#xff01;今年 2 月&#xff0c;开源数据库厂商 MariaDB 完成了 1.04 亿美元的 D 轮融资&#xff0c;同…

太阳粒子是什么东西_太阳光子前世今生告诉我们现在享受之阳光是十几万年前诞生的老光...

我们都知道天晴时阳光明媚&#xff0c;但这个阳光是怎么来的呢&#xff0c;很多人就不一定清楚了。在这里我们首先来了解几个概念&#xff1a;光子、光、电磁波、电磁辐射。光子是传递电磁波相互作用的基本粒子&#xff0c;是一种规范波色子&#xff0c;是电磁辐射的载体&#…

java 观察者模式示例_观察者设计模式示例

java 观察者模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 …

int类型存小数 mysql_MySQL基本数据类型

1&#xff09;整形1.介绍分类&#xff1a;tinyint , smallint , mediumint , int , bigint 应用场景&#xff1a;存储年龄&#xff0c;等级&#xff0c;id&#xff0c;各种号码等典型存储范围介绍:https://images2017.cnblogs.com/blog/1036857/201708/1036857-201708011814337…

枚举重名_举重设计模式示例

枚举重名本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#xff01…

装饰着模式示例_装饰器设计模式示例

装饰着模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &…

强烈推荐!10个超赞的C语言开源项目

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络今天给大家分享10个超赞的C语言开源项目&#xff0c;希望这些内容能对大家有所帮助&#xff01;01WebbenchWebbench是一个在 L…

以外的文件 删除_原来C盘还可以删除这五个文件,难怪电脑越来越卡!

马上就要年底了&#xff0c;大家肯定都是欢欢喜喜准备过年&#xff0c;将家里变得焕然一新。韩博士也捯饬好大包小包打算风风火火赶回家&#xff0c;结果刚打开电脑&#xff0c;哦豁&#xff0c;立马卡到爆炸。想着都年底了&#xff0c;这电脑还打算给我搞出什么幺蛾子&#xf…

设计模式示例_复合设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

给大家收集了一些C语言代码优化的方法!

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络在本篇文章中&#xff0c;我收集了很多经验和方法。应用这些经验和方法&#xff0c;可以帮助我们从执行速度和内存使用等方面来…

设计模式示例_介体设计模式示例

设计模式示例本文是我们名为“ Java设计模式 ”的学院课程的一部分。 在本课程中&#xff0c;您将深入研究大量的设计模式&#xff0c;并了解如何在Java中实现和利用它们。 您将了解模式如此重要的原因&#xff0c;并了解何时以及如何应用模式中的每一个。 在这里查看 &#x…

清空list_还在为邮箱爆掉而烦恼吗?学会清空你的收件箱

less is more | 越不繁&#xff0c;越不凡还在为邮箱爆掉而烦恼吗&#xff1f;学会清空你的收件箱我一般只用Gmail收发邮件&#xff0c;而且处理邮件已经成为日常工作的核心之一。我每个小时能收到大量邮件&#xff0c;并且快速回复。但是&#xff0c;有一件事要特别提一下&…

这才是B站的正确打开方式!

关注星标&#xff0c;每天学习C语言新技能因公众号更改推送规则&#xff0c;请点“在看”并加“星标”第一时间获取精彩技术分享来源&#xff1a;网络每天都在用B站刷杂七杂八的视频&#xff0c;有没有考虑过挖掘一些优质UP主&#xff1f;想要发掘优质UP主&#xff0c;靠B站官方…

pcl_openmap_OpenMap教程–第1部分

pcl_openmap介绍 本系列教程将向您展示如何使用OpenMap GIS Java Swing库构建Java应用程序。 OpenMap的开发人员指南是非常有用的文档&#xff0c;描述了OpenMap的体系结构&#xff0c;但没有说明如何逐步启动和构建应用程序。 源代码附带的示例很有用&#xff0c;但还不够。 …

网页编程从入门到精通 杨凡_干货 | web前端入门基础知识

一名合格的web前端工程师必须得掌握HTML、CSS和JavaScript。只懂其中一个或两个还不行&#xff0c;你必须对这三门语言都很熟悉。也不是说必须对这三门语言都非常精通&#xff0c;但你至少要能够运用它们完成大多数任务&#xff0c;而无需地频繁地寻求别人的帮助。今天给大家分…