当前位置: 首页 > news >正文

做网站页面多少钱外包seo公司

做网站页面多少钱,外包seo公司,网站建设模板制作,节能网站源码Spring Boot 的自动配置特性能够大大简化集成外部服务和组件的配置过程。以 RabbitMQ 为例#xff0c;Spring Boot 通过 spring-boot-starter-amqp 提供了自动配置支持#xff0c;开发者只需在应用中添加相关依赖并配置必要的属性#xff0c;Spring Boot 会自动配置所需的连…Spring Boot 的自动配置特性能够大大简化集成外部服务和组件的配置过程。以 RabbitMQ 为例Spring Boot 通过 spring-boot-starter-amqp 提供了自动配置支持开发者只需在应用中添加相关依赖并配置必要的属性Spring Boot 会自动配置所需的连接工厂、消息队列、交换机、消息模板等。 以下是以 RabbitMQ 为例的详细说明。 1. 引入 RabbitMQ 依赖 要使用 Spring Boot 集成 RabbitMQ首先需要在项目的 pom.xml 文件中添加 spring-boot-starter-amqp 依赖这个依赖包含了与 RabbitMQ 交互的所有必要组件。 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-amqp/artifactId /dependencyspring-boot-starter-amqp 依赖包含了 Spring AMQP 和 RabbitMQ 的连接组件自动配置会根据此依赖自动启用 RabbitMQ 相关功能。 2. 配置 RabbitMQ 连接属性 接下来你需要在 application.properties 或 application.yml 中配置 RabbitMQ 的连接信息。例如 使用 application.properties spring.rabbitmq.hostlocalhost spring.rabbitmq.port5672 spring.rabbitmq.usernameguest spring.rabbitmq.passwordguest spring.rabbitmq.virtual-host/ spring.rabbitmq.publisher-confirm-typesimple spring.rabbitmq.listener.simple.concurrency3 spring.rabbitmq.listener.simple.max-concurrency10spring.rabbitmq.hostRabbitMQ 服务器的地址通常是 localhost。spring.rabbitmq.portRabbitMQ 服务器的端口默认是 5672。spring.rabbitmq.username 和 spring.rabbitmq.passwordRabbitMQ 的认证信息。spring.rabbitmq.virtual-host虚拟主机通常是 /。spring.rabbitmq.publisher-confirm-type确认模式simple 为简单确认。spring.rabbitmq.listener.simple.concurrency并发消费者数量。spring.rabbitmq.listener.simple.max-concurrency最大消费者数量。 Spring Boot 会读取这些配置并自动配置连接工厂、消息队列监听器等。 3. 自动配置的原理 Spring Boot 在启动时会通过 spring-boot-autoconfigure 模块自动配置 RabbitMQ 相关的 Bean主要通过以下几个步骤 3.1 自动配置连接工厂ConnectionFactory Spring Boot 会根据 spring.rabbitmq.* 配置自动创建一个 ConnectionFactory它负责与 RabbitMQ 服务器建立连接。通常Spring Boot 默认使用 CachingConnectionFactory 来实现连接工厂。 Bean Primary ConditionalOnMissingBean(ConnectionFactory.class) public CachingConnectionFactory connectionFactory() {CachingConnectionFactory connectionFactory new CachingConnectionFactory();connectionFactory.setHost(rabbitProperties.getHost());connectionFactory.setPort(rabbitProperties.getPort());connectionFactory.setUsername(rabbitProperties.getUsername());connectionFactory.setPassword(rabbitProperties.getPassword());connectionFactory.setVirtualHost(rabbitProperties.getVirtualHost());return connectionFactory; }ConditionalOnMissingBean 表示如果应用上下文中没有 ConnectionFactory 的 BeanSpring Boot 会创建一个默认的 CachingConnectionFactory。配置的 spring.rabbitmq.* 参数将被注入到这个 ConnectionFactory 中。 3.2 自动配置 RabbitTemplate RabbitTemplate 是 Spring AMQP 用来发送消息的核心类。Spring Boot 会自动配置一个 RabbitTemplate它使用 ConnectionFactory 来与 RabbitMQ 服务器进行交互。 Bean ConditionalOnMissingBean(RabbitTemplate.class) public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate template new RabbitTemplate(connectionFactory);template.setMessageConverter(new Jackson2JsonMessageConverter());return template; }RabbitTemplate 被用来发送消息Spring Boot 自动创建并配置。默认使用 JSON 消息转换器Jackson2JsonMessageConverter将消息转换为 JSON 格式。 3.3 自动配置 RabbitListenerContainerFactory 如果你想使用 RabbitListener 注解来监听 RabbitMQ 消息队列Spring Boot 会自动配置 RabbitListenerContainerFactory。 Bean ConditionalOnMissingBean(RabbitListenerContainerFactory.class) public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory; }这个工厂用于创建 RabbitMQ 消息监听容器容器负责消费队列中的消息。setConcurrency 和 setMaxConcurrency 用来配置消息消费者的并发数。 3.4 自动配置消息监听器RabbitListener Spring Boot 会自动启用对 RabbitListener 注解的支持。你可以使用 RabbitListener 注解创建消息监听器而无需手动配置监听容器。 4. 创建消费者和生产者 4.1 消息生产者发送消息 你可以使用 RabbitTemplate 发送消息到 RabbitMQ 队列。 import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;Service public class MessageProducer {Autowiredprivate RabbitTemplate rabbitTemplate;public void sendMessage(String message) {rabbitTemplate.convertAndSend(myQueue, message);} }rabbitTemplate.convertAndSend 方法用于将消息发送到指定的队列myQueue。Spring Boot 会自动为你配置队列、交换机、路由等。 4.2 消息消费者监听消息 你可以使用 RabbitListener 注解来创建消息消费者监听指定的队列并在消息到达时处理它。 import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Service;Service public class MessageConsumer {RabbitListener(queues myQueue)public void receiveMessage(String message) {System.out.println(Received message: message);} }RabbitListener 注解会告诉 Spring Boot 自动创建一个消息监听器并连接到指定的队列。每当有消息进入 myQueue 队列时receiveMessage 方法就会被调用。 5. 自定义配置 你可以进一步自定义 RabbitMQ 的配置以下是一些常见的自定义场景 5.1 配置交换机、队列和绑定 你可以定义自己的交换机、队列和绑定确保它们符合你的应用需求。例如 import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public class RabbitConfig {Beanpublic Queue myQueue() {return new Queue(myQueue, true);}Beanpublic TopicExchange exchange() {return new TopicExchange(myExchange);}Beanpublic Binding binding(Queue myQueue, TopicExchange exchange) {return BindingBuilder.bind(myQueue).to(exchange).with(myQueue.#);} }Queue 定义了一个消息队列。TopicExchange 定义了一个交换机。Binding 定义了队列和交换机之间的绑定关系。 5.2 配置消息监听器的并发 你可以通过 application.properties 或 application.yml 来调整消息监听器的并发配置 spring.rabbitmq.listener.simple.concurrency5 spring.rabbitmq.listener.simple.max-concurrency10这将允许 Spring Boot 动态调整消费者线程的数量确保队列消息能够高效消费。 总结 Spring Boot 通过自动配置 RabbitMQ 连接、消息发送和消费等相关组件极大地简化了 RabbitMQ 的集成过程。只需添加 spring-boot-starter-amqp 依赖并在配置文件中指定必要的参数Spring Boot 就会自动配置所需的所有组件并根据需求自动启动消息生产者和消费者。你可以通过注解 RabbitListener 来定义消息监听器也可以自定义交换机、队列和绑定等配置从而满足不同的业务需求。 通过源码再次详细说明 要深入了解 Spring Boot 如何通过自动配置集成 RabbitMQ我们需要通过源码分析它是如何工作的。Spring Boot 使用了 spring-boot-starter-amqp 来简化 RabbitMQ 的配置。以下是从源代码角度对 Spring Boot 如何自动配置 RabbitMQ 进行详细说明的过程。 1. Spring Boot 启动流程和自动配置 Spring Boot 使用了 EnableAutoConfiguration 注解和 spring.factories 文件来实现自动配置。在启动时Spring Boot 会扫描并自动配置与应用上下文相关的配置类。RabbitMQ 的自动配置就是通过这些配置类实现的。 1.1 spring-boot-starter-amqp 依赖 首先spring-boot-starter-amqp 依赖包含了 Spring AMQP 和 RabbitMQ 的集成依赖并提供了 RabbitMQ 自动配置的支持。它的 spring.factories 文件列出了与 RabbitMQ 相关的自动配置类。 在 spring-boot-starter-amqp 中spring.factories 文件会自动引入 RabbitAutoConfiguration 类。你可以在 spring-boot-starter-amqp 依赖中看到这一点 dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-amqp/artifactId /dependency当你引入了这个依赖后Spring Boot 会自动加载 RabbitMQ 的相关配置。 2. RabbitAutoConfiguration 类 Spring Boot 的 RabbitMQ 自动配置类是 RabbitAutoConfiguration它位于 org.springframework.boot.autoconfigure.amqp 包中。这个类的作用是基于你的配置自动设置 RabbitMQ 连接、队列、交换机等。 我们来分析一下 RabbitAutoConfiguration 类的源码 Configuration(proxyBeanMethods false) ConditionalOnClass(CachingConnectionFactory.class) ConditionalOnProperty(prefix spring.rabbitmq, name host) EnableConfigurationProperties(RabbitProperties.class) Import({ RabbitListenerConfiguration.class, RabbitManagementConfigurer.class }) public class RabbitAutoConfiguration {private static final Logger logger LoggerFactory.getLogger(RabbitAutoConfiguration.class);private final RabbitProperties properties;public RabbitAutoConfiguration(RabbitProperties properties) {this.properties properties;}BeanConditionalOnMissingBean(ConnectionFactory.class)public CachingConnectionFactory connectionFactory() {logger.debug(Creating CachingConnectionFactory);CachingConnectionFactory factory new CachingConnectionFactory();factory.setHost(this.properties.getHost());factory.setPort(this.properties.getPort());factory.setUsername(this.properties.getUsername());factory.setPassword(this.properties.getPassword());factory.setVirtualHost(this.properties.getVirtualHost());return factory;}BeanConditionalOnMissingBean(RabbitTemplate.class)public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());return rabbitTemplate;}BeanConditionalOnMissingBean(SimpleRabbitListenerContainerFactory.class)public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory;} }2.1 Configuration 和 EnableConfigurationProperties Configuration(proxyBeanMethods false)这是一个配置类proxyBeanMethods false 表示这个配置类不会使用代理也就是说它只会影响当前类中定义的 bean。EnableConfigurationProperties(RabbitProperties.class)该注解使得 RabbitProperties 类成为一个配置属性类允许 Spring Boot 自动加载配置文件中的 spring.rabbitmq.* 属性并将它们绑定到 RabbitProperties 对象。 2.2 connectionFactory Bean Bean ConditionalOnMissingBean(ConnectionFactory.class) public CachingConnectionFactory connectionFactory() {CachingConnectionFactory factory new CachingConnectionFactory();factory.setHost(this.properties.getHost());factory.setPort(this.properties.getPort());factory.setUsername(this.properties.getUsername());factory.setPassword(this.properties.getPassword());factory.setVirtualHost(this.properties.getVirtualHost());return factory; }ConditionalOnMissingBean(ConnectionFactory.class)这表示如果应用上下文中没有 ConnectionFactory 类型的 BeanSpring Boot 会自动创建一个 CachingConnectionFactory 的实例。CachingConnectionFactory 是 Spring AMQP 提供的一个连接工厂实现它能缓存到 RabbitMQ 的连接以提高性能。factory.setHost 等这些配置项通过 RabbitProperties 类从 application.properties 或 application.yml 中读取并注入。 2.3 rabbitTemplate Bean Bean ConditionalOnMissingBean(RabbitTemplate.class) public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());return rabbitTemplate; }ConditionalOnMissingBean(RabbitTemplate.class)如果 RabbitTemplate 已经存在于应用上下文中Spring Boot 就不会再次创建它。RabbitTemplate它是与 RabbitMQ 交互的核心类主要用于发送消息。Spring Boot 会自动创建并配置 RabbitTemplate并将其与上面创建的 ConnectionFactory 关联。 2.4 rabbitListenerContainerFactory Bean Bean ConditionalOnMissingBean(SimpleRabbitListenerContainerFactory.class) public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory, RabbitProperties rabbitProperties) {SimpleRabbitListenerContainerFactory factory new SimpleRabbitListenerContainerFactory();factory.setConnectionFactory(connectionFactory);factory.setConcurrency(rabbitProperties.getListener().getSimple().getConcurrency());factory.setMaxConcurrency(rabbitProperties.getListener().getSimple().getMaxConcurrency());return factory; }SimpleRabbitListenerContainerFactory这是一个用来创建 RabbitMQ 消息监听容器的工厂。该容器负责从 RabbitMQ 中接收并处理消息。setConcurrency 和 setMaxConcurrency这两个方法控制监听器的并发性指定了消息监听的最小和最大并发数。 3. RabbitListenerConfiguration 和 RabbitManagementConfigurer RabbitAutoConfiguration 类还通过 Import 注解引入了 RabbitListenerConfiguration 和 RabbitManagementConfigurer 类。这些类负责配置消息监听器和管理接口等。 java Import({ RabbitListenerConfiguration.class, RabbitManagementConfigurer.class }) RabbitListenerConfiguration负责配置和启用 RabbitListener 注解的处理。RabbitManagementConfigurer负责 RabbitMQ 管理的配置通常是为了启用或配置 RabbitMQ 管理界面。 4. RabbitProperties 类 RabbitProperties 类是用来封装 application.properties 或 application.yml 中与 RabbitMQ 相关的配置项的。它的主要作用是将这些配置绑定到 Java 对象上方便后续使用。 ConfigurationProperties(prefix spring.rabbitmq) public class RabbitProperties {private String host localhost;private int port 5672;private String username guest;private String password guest;private String virtualHost /;private Listener listener new Listener();public static class Listener {private Simple simple new Simple();public static class Simple {private int concurrency 1;private int maxConcurrency 1;}}// getters and setters }RabbitProperties 是一个 POJO 类Spring Boot 会将 application.properties 中以 spring.rabbitmq.* 开头的属性自动映射到这个类的字段中。 5. RabbitListener 注解支持 Spring Boot 自动配置还会启用 RabbitListener 注解的支持这意味着你可以通过注解驱动的方式来创建 RabbitMQ 消息监听器。例如 Service public class MyListener {RabbitListener(queues myQueue)public void handleMessage(String message) {System.out.println(Received message: message);} }6. 总结 通过 RabbitAutoConfigurationSpring Boot 自动配置了与 RabbitMQ 交互所需的主要组件ConnectionFactory、RabbitTemplate、SimpleRabbitListenerContainerFactory 等。这些组件的创建是基于 application.properties 中的配置完成的。通过 Spring Boot 的自动配置开发者只需要添加必要的依赖和配置不必手动创建和配置这些复杂的 RabbitMQ 组件。 自动配置总结 ConnectionFactory用于连接到 RabbitMQ 服务。RabbitTemplate用于发送消息。SimpleRabbitListenerContainerFactory用于配置消息监听容器。RabbitListener 注解用于处理消息监听。 RabbitAutoConfiguration 源码 1.5.9版本 // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //package org.springframework.boot.autoconfigure.amqp;import com.rabbitmq.client.Channel; import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Retry; import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Ssl; import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Template; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.policy.SimpleRetryPolicy; import org.springframework.retry.support.RetryTemplate;Configuration ConditionalOnClass({RabbitTemplate.class, Channel.class}) EnableConfigurationProperties({RabbitProperties.class}) Import({RabbitAnnotationDrivenConfiguration.class}) public class RabbitAutoConfiguration {public RabbitAutoConfiguration() {}ConfigurationConditionalOnClass({RabbitMessagingTemplate.class})ConditionalOnMissingBean({RabbitMessagingTemplate.class})Import({RabbitAutoConfiguration.RabbitTemplateConfiguration.class})protected static class MessagingTemplateConfiguration {protected MessagingTemplateConfiguration() {}BeanConditionalOnSingleCandidate(RabbitTemplate.class)public RabbitMessagingTemplate rabbitMessagingTemplate(RabbitTemplate rabbitTemplate) {return new RabbitMessagingTemplate(rabbitTemplate);}}ConfigurationImport({RabbitAutoConfiguration.RabbitConnectionFactoryCreator.class})protected static class RabbitTemplateConfiguration {private final ObjectProviderMessageConverter messageConverter;private final RabbitProperties properties;public RabbitTemplateConfiguration(ObjectProviderMessageConverter messageConverter, RabbitProperties properties) {this.messageConverter messageConverter;this.properties properties;}BeanConditionalOnSingleCandidate(ConnectionFactory.class)ConditionalOnMissingBean({RabbitTemplate.class})public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {RabbitTemplate rabbitTemplate new RabbitTemplate(connectionFactory);MessageConverter messageConverter (MessageConverter)this.messageConverter.getIfUnique();if (messageConverter ! null) {rabbitTemplate.setMessageConverter(messageConverter);}rabbitTemplate.setMandatory(this.determineMandatoryFlag());Template templateProperties this.properties.getTemplate();Retry retryProperties templateProperties.getRetry();if (retryProperties.isEnabled()) {rabbitTemplate.setRetryTemplate(this.createRetryTemplate(retryProperties));}if (templateProperties.getReceiveTimeout() ! null) {rabbitTemplate.setReceiveTimeout(templateProperties.getReceiveTimeout());}if (templateProperties.getReplyTimeout() ! null) {rabbitTemplate.setReplyTimeout(templateProperties.getReplyTimeout());}return rabbitTemplate;}private boolean determineMandatoryFlag() {Boolean mandatory this.properties.getTemplate().getMandatory();return mandatory ! null ? mandatory : this.properties.isPublisherReturns();}private RetryTemplate createRetryTemplate(Retry properties) {RetryTemplate template new RetryTemplate();SimpleRetryPolicy policy new SimpleRetryPolicy();policy.setMaxAttempts(properties.getMaxAttempts());template.setRetryPolicy(policy);ExponentialBackOffPolicy backOffPolicy new ExponentialBackOffPolicy();backOffPolicy.setInitialInterval(properties.getInitialInterval());backOffPolicy.setMultiplier(properties.getMultiplier());backOffPolicy.setMaxInterval(properties.getMaxInterval());template.setBackOffPolicy(backOffPolicy);return template;}BeanConditionalOnSingleCandidate(ConnectionFactory.class)ConditionalOnProperty(prefix spring.rabbitmq,name {dynamic},matchIfMissing true)ConditionalOnMissingBean({AmqpAdmin.class})public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {return new RabbitAdmin(connectionFactory);}}ConfigurationConditionalOnMissingBean({ConnectionFactory.class})protected static class RabbitConnectionFactoryCreator {protected RabbitConnectionFactoryCreator() {}Beanpublic CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config) throws Exception {RabbitConnectionFactoryBean factory new RabbitConnectionFactoryBean();if (config.determineHost() ! null) {factory.setHost(config.determineHost());}factory.setPort(config.determinePort());if (config.determineUsername() ! null) {factory.setUsername(config.determineUsername());}if (config.determinePassword() ! null) {factory.setPassword(config.determinePassword());}if (config.determineVirtualHost() ! null) {factory.setVirtualHost(config.determineVirtualHost());}if (config.getRequestedHeartbeat() ! null) {factory.setRequestedHeartbeat(config.getRequestedHeartbeat());}Ssl ssl config.getSsl();if (ssl.isEnabled()) {factory.setUseSSL(true);if (ssl.getAlgorithm() ! null) {factory.setSslAlgorithm(ssl.getAlgorithm());}factory.setKeyStore(ssl.getKeyStore());factory.setKeyStorePassphrase(ssl.getKeyStorePassword());factory.setTrustStore(ssl.getTrustStore());factory.setTrustStorePassphrase(ssl.getTrustStorePassword());}if (config.getConnectionTimeout() ! null) {factory.setConnectionTimeout(config.getConnectionTimeout());}factory.afterPropertiesSet();CachingConnectionFactory connectionFactory new CachingConnectionFactory((com.rabbitmq.client.ConnectionFactory)factory.getObject());connectionFactory.setAddresses(config.determineAddresses());connectionFactory.setPublisherConfirms(config.isPublisherConfirms());connectionFactory.setPublisherReturns(config.isPublisherReturns());if (config.getCache().getChannel().getSize() ! null) {connectionFactory.setChannelCacheSize(config.getCache().getChannel().getSize());}if (config.getCache().getConnection().getMode() ! null) {connectionFactory.setCacheMode(config.getCache().getConnection().getMode());}if (config.getCache().getConnection().getSize() ! null) {connectionFactory.setConnectionCacheSize(config.getCache().getConnection().getSize());}if (config.getCache().getChannel().getCheckoutTimeout() ! null) {connectionFactory.setChannelCheckoutTimeout(config.getCache().getChannel().getCheckoutTimeout());}return connectionFactory;}} }
http://www.yingshimen.cn/news/82444/

相关文章:

  • wap网站多少钱国外jquery网站
  • 绍兴网站建设开发亚马逊市场营销案例分析
  • 水果销售网站开发文献综述门户网站盈利模式
  • 网站设计特点wordpress站长地图
  • 路南网站建设专业的深圳网站设计
  • 小白学做网站教程成都seo优化推广
  • 织梦移动网站做百度网站要多少钱
  • 广州推广网站东莞市专注网站建设服务机构
  • 广州天华建筑设计有限公司云南网站优化建站
  • 四川建设厅电子证书官方网站永德网站建设
  • 建设部网站令第77号济南网站建设服务公司
  • 东道设计理念分析seo网站
  • 蚌埠市做网站备案 增加网站
  • 怎么做视频还有网站吗中山市哪家公司做网站
  • 深圳海洋网络做网站十大免费看盘软件
  • 建立一个购物网站东平县住房和建设局网站
  • 网站权重有时降wordpress 浮动导航插件
  • 龙岩网站设计价格谷歌俄语网站
  • 2008r2 iis网站验证码不显示苏州有什么好玩的地方
  • 汕头站扩建后比哪个站大网站前端设计外包公司
  • 福州网站快速排名平台设计图
  • 怎么在自己的电脑做网站织梦手机网站怎么修改密码
  • 漯河公司做网站成都设计公司第一名
  • 在深圳怎么进大公司网站如何自己做小程序免费
  • 乐清网站优化推广wordpress 服务器配置
  • 江苏中小企业网站建设合肥网站建设程序
  • 临海如何制作公司网站框架wordpress微信登录插件下载失败
  • 定制网站建设服务公司非凡免费建网站平台
  • 深圳网站制作哪家便宜dx网站是哪家公司做的
  • 山东省住房城乡建设厅网站首页公司网站关键词优化