SpringBoot01--运行原理和自动装配原理

2023-10-30


三步:“是什么?”、“怎么做?”、“为什么?”

一、是什么

1.Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化Spring应用的初始搭建以及开发过程。

2.使用 Spring Boot 可以很容易地创建出能直接运行的独立的、生产级别的基于 Spring 的应用。我们对 Spring 平台和第三方类库有自己的考虑,因此您可以从最基本的开始。大多数 Spring Boot 应用只需要很少的 Spring 配置。

3.您可以使用 Spring Boot 来创建一个可以使用 java -jar 命令来运行或者基于传统的 war 包部署的应用程序。我们还提供了一个用于运行 spring scripts 的命令行工具。

4.Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。

5.简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。

目标:

  • 为所有 Spring Boot 开发提供一个更快、更全面的入门体验。
  • 坚持自我虽好,但当需求出现偏离,您需要能迅速摆脱出来。
  • 提供大量非功能性特性相关项目(例如:内嵌服务器、安全、指标、健康检查、外部配置)。
  • 绝对没有代码生成,也不要求 XML 配置。

二、SpringBoot优点

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

两个重要策略:

SpringBoot框架中还有两个非常重要的策略:开箱即用和约定优于配置。

  • 开箱即用,Outofbox,是指在开发过程中,通过在MAVEN项目的pom文件中添加相关依赖包,然后使用对应注解来代替繁琐的XML配置文件以管理对象的生命周期。这个特点使得开发人员摆脱了复杂的配置工作以及依赖的管理工作,更加专注于业务逻辑。
  • 约定优于配置,Convention over configuration,是一种由SpringBoot本身来配置目标结构,由开发者在结构中添加信息的软件设计范式。这一特点虽降低了部分灵活性,增加了BUG定位的复杂性,但减少了开发人员需要做出决定的数量,同时减少了大量的XML配置,并且可以将代码编译、测试和打包等工作自动化。

来吧按照惯例整个helloworld

创建一个新项目

1、选择spring initalizr , 可以看到默认就是去官网的快速构建工具那里实现

2、填写项目信息

3、选择初始化的组件勾选web

4、填写项目路径

5、等待项目构建成功

这里注意,查看pom文件时可能会遇到spring-boot-maven-plugin爆红的问题,这里把你的maven仓库改为本地的

看一下pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- 父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.shy</groupId>
    <artifactId>hello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!-- web场景启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- springboot单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!-- 打包插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

编写一个HelloController,注意controller包跟你的主启动类同级~

package com.shy.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello(){
        return "hello world~";
    }
}

去主启动类启动项目

打开浏览器输入http://localhost:8080/hello就可以喽~

helloworld结束~

打成jar包就可以在任何地方运行了

步骤:右边maven,点击package,然后install,成功之后在target目录下生成一个jar包

三、运行原理

1.从pom.xml开始

​ 父依赖:其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!

<!-- 父依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

​ 摁住ctrl点击2.4.5

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.4.5</version>
  </parent>

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;

以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了

2.启动器 spring-boot-starter

		<!-- web场景启动器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

springboot-boot-starter-xxx:就是spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;

3.主启动类

package com.shy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class HelloApplication {
	//启动服务
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

4.但是**一个简单的启动类并不简单!**我们来分析一下这些注解都干了什么

@SpringBootApplication

还是摁住ctrl点击这个注解,进去之后

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {...}

前四个注解早就见过了,重点说下面的几个

@ComponentScan

​ 这个注解在Spring中很重要 ,它对应XML配置中的元素。

​ 作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@SpringBootConfiguration

​ 作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

​ 点进去瞅瞅~

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {...}

​ 这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

​ 继续点@Configuration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {...}

​ 里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!到这就ok了,回去吧

​ 回到 SpringBootApplication 。

@EnableAutoConfiguration开启自动配置功能

​ 以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;@EnableAutoConfiguration告诉SpringBoot开启自动配置 功能,这样自动配置才能生效;

​ 点进去瞅瞅~

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {...}

@AutoConfigurationPackage :自动配置包

​ 点进去

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {...}

@import :Spring底层注解@import , 给容器中导入一个组件

​ AutoConfigurationPackages.Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

​ 退回上一步

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 ;

​ AutoConfigurationImportSelector :自动配置导入选择器,点进去,有这么一个方法

// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in META-			INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
}

​ 这里的getSpringFactoriesLoaderFactoryClass()方法
​ 返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration

protected Class<?> getSpringFactoriesLoaderFactoryClass() {
		return EnableAutoConfiguration.class;
}

​ 这个方法又调用了 SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		String factoryTypeName = factoryType.getName();
    	//这里它又调用了 loadSpringFactories 方法
		return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}

​ 点击查看 loadSpringFactories 方法

private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
		//获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
    	Map<String, List<String>> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		result = new HashMap<>();
		try {
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
            //将读取到的资源遍历,封装成为一个Properties
			while (urls.hasMoreElements()) {
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
					String factoryTypeName = ((String) entry.getKey()).trim();
					String[] factoryImplementationNames =
							StringUtils.commaDelimitedListToStringArray((String) entry.getValue());
					for (String factoryImplementationName : factoryImplementationNames) {
						result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())
								.add(factoryImplementationName.trim());
					}
				}
			}

			// Replace all lists with unmodifiable lists containing unique elements
			result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()
					.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));
			cache.put(classLoader, result);
		}
		catch (IOException ex) {
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
		return result;
	}

​ 继续点击FACTORIES_RESOURCE_LOCATION

//去获取一个资源 "META-INF/spring.factories"
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

发现一个多次出现的文件:spring.factories,全局搜索它 按两下shift,搜索,点击files

打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在!这些文件都可以点进去~

点击你本地仓库的那个,后面不是跟着路径嘛~

自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

结论:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

SpringApplication

package com.shy;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//@SpringBootApplication 来标注一个主程序类
//说明这是一个Spring Boot应用
@SpringBootApplication
public class HelloApplication {
	//启动服务
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

点进去,找她的构造方法

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		this.bootstrapRegistryInitializers = getBootstrapRegistryInitializersFromSpringFactories();
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

四、Springboot注解

1.@SpringBootApplication:该注解是springboot最核心注解,也是组合注解,声明它就可以让springboot自动给程序进行必要的配置(简单的说,开启组件扫描和自己配置的功能)。

包含了**@ComponentScan**、@Configuration和**@EnableAutoConfiguration**注解。

2.@Configuration 等同于spring的XML配置文件;使用Java代码可以检查类型安全。

3.@EnableAutoConfiguration 自动配置。

4.@SpringBootConfiguration:是标志当前的类的配置类。

5.@ComponentScan 组件扫描,可自动发现和装配一些Bean。

6.@Component可配合CommandLineRunner使用,在程序启动后执行一些基础任务。

7.@RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器bean,并且是将函数的返回值直 接填入HTTP响应体中,是REST风格的控制器。

8.@Controller:该注解用于定义控制器,在spring项目中是由控制器负责用户发来的请求,然后控制器将用户请求的URL转发到对应的接口service层,进行调用相应的业务,在使用该注解时,还用结合@RequestMapping一起使用,处理http请求。

9**.@ResponseBody**:使用该注解表示方法的返回结果直接写入HTTP response body中的,当我们异步请求的时候常使用,用于构建restful的API。

10.@Repository:该注解用于标注数据访问组件,DAO组件的。

11.@service:该注解使用于标注业务层,当在业务层的类上使用时,bean就是自动找到该类就是service的。

12.@PathVariable:该注解使用来绑定函数中的参数用于获取参数的,当默认的情况下,spring会对@该注解的变量进行自动赋值的,我们也可以自己指定。

13.@RequestParam注解:是指获取请求参数的值,@GetMapping是组合注解。

14.@Autowired自动导入。

15.@JsonBackReference解决嵌套外链问题。

16.@RepositoryRestResourcepublic配合spring-boot-starter-data-rest使用。

17.@Transactional: 通过这个注解可以声明事务,可以添加在类上或者方法上。

18.@Resource:@Resource和@Autowired一样都可以用来装配bean,都可以标注字段上,或者方法上。 @resource注解不是spring提供的,是属于J2EE规范的注解。 两个之前的区别就是匹配方式上有点不同,@Resource默认按照名称方式进行bean匹配,@Autowired默认按照类型方式进行bean匹配。

19.资源导入注解:@ImportResource @Import @PropertySource,这三个注解都是用来导入自定义的一些配置文件。

@ImportResource (locations={})导入其他xml配置文件,需要标注在主配置类上,导入property的配置文件@PropertySource指定文件路径,相当于使用spring的标签来完成配置项的引入。@import注解是一个可以将普通类导入到spring容器中做管理

20.@ServletComponentScan:Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,这样通过注解servlet ,拦截器,监听器的功能而无需其他配置,所以这次相中使用到了filter的实现,用到了这个注解。

21.@MapperScan:spring-boot支持mybatis组件的一个注解,通过此注解指定mybatis接口类的路径,即可完成对mybatis接口的扫描。它和@mapper注解是一样的作用,不同的地方是扫描入口不一样。@mapper需要加在每一个mapper接口类上面。所以大多数情况下,都是在规划好工程目录之后,通过@MapperScan注解配置路径完成mapper接口的注入。

五、自动装配原理

1、加载META-INF/spring-autoconfigure-metadata.properties文件

2、获取注解的属性及其值(PS:注解指的是@EnableAutoConfiguration注解)

3、从classpath中搜索所有META-INF/spring.factories配置文件然后,将其中

org.springframework.boot.autoconfigure.EnableAutoConfiguration key对应的配置项加载到spring容器。只有spring.boot.enableautoconfiguration为true(默认为true)的时候,才启用自动配置,最终得到EnableAutoConfiguration的配置值,并将其封装到一个List中返回。

4、对上一步返回的List中的元素去重、排序。

5、依据第2步中获取的属性值排除一些特定的类,排除方式有两种,一是根据class来排除(exclude),二是根据classname(excludeName)来排除。

6、对上一步中所得到的List进行过滤,过滤的依据是条件匹配。这里用到的过滤器是org.springframework.boot.autoconfigure.condition.OnClassCondition最终返回的是一个ConditionOutcome[]数组。(PS:很多类都是依赖于其它的类的,当有某个类时才会装配,所以这次过滤的就是根据是否有某个class进而决定是否装配的。这些类所依赖的类都写在META-INF/spring-autoconfigure-metadata.properties文件里)

关键点

1、ImportSelector 该接口的方法的返回值都会被纳入到spring容器管理中

2、SpringFactoriesLoader 该类可以从classpath中搜索所有META-INF/spring.factories配置文件,并读取配置。同理,其实Spring框架本身也提供了几个名字为@Enable开头的Annotation定义。比如@EnableScheduling、@EnableCaching、@EnableMBeanExport等,@EnableAutoConfiguration的理念和这些注解其实是一脉相承的。

观察@EnableAutoConfiguration可以发现,这里Import了@EnableAutoConfigurationImportSelector,这就是Spring Boot自动化配置的“始作俑者”。

至此,我们知道,由于我们在Spring Boot的启动类上使用了@SpringBootApplication注解,而该注解组合了@EnableAutoConfiguration注解,@EnableAutoConfiguration是自动化配置的“始作俑者”,而@EnableAutoConfiguration中Import了@EnableAutoConfigurationImportSelector注解,该注解的内部通过SpringFactoriesLoader.loadFactoryNames()读取了ClassPath下面的META-INF/spring.factories文件中key为的字符串数组,然后加载字节码,最后纳入到Spring IOC容器中~

根据当前不同的条件判断,决定这个配置类是否生效

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类

**xxxxAutoConfigurartion:自动配置类;**给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

自动配置类必须在一定的条件下才能生效

@Conditional派生注解(Spring注解版原生的@Conditional作用)

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

#开启springboot的调试类
debug=true

Positive matches:(自动配置类启用的:正匹配)

Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

Unconditional classes: (没有条件的类)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot01--运行原理和自动装配原理 的相关文章

  • Java 中的 XPath 节点集

    我在 eclipse 中有这段代码 NodeSet nodes NodeSet xPath evaluate expression inputSource XPathConstants NODESET 它给我 NodeSet 上的编译时错误
  • 如果测试用例失败,Selenium Web 驱动程序无法关闭 Firefox 实例

    我各位 我正在使用 junit 和 selenium web 驱动程序 2 28 问题是 如果我运行成功的测试用例 Web 驱动器能够关闭 Firefox 实例 但是当测试用例失败时 Selenium Web 驱动器无法关闭 Firefox
  • 如何使用 FileChannel 将一个文件的内容附加到另一个文件的末尾?

    File a txt好像 ABC File d txt好像 DEF 我正在尝试将 DEF 附加到 ABC 所以a txt好像 ABC DEF 我尝试过的方法总是完全覆盖第一个条目 所以我总是最终得到 DEF 这是我尝试过的两种方法 File
  • Java程序中的数组奇怪的行为[重复]

    这个问题在这里已经有答案了 我遇到了这个 Java 程序及其以意想不到的方式运行 以下程序计算 int 数组中元素对之间的差异 import java util public class SetTest public static void
  • JNI 不满意链接错误

    我想创建一个简单的 JNI 层 我使用Visual studio 2008创建了一个dll Win 32控制台应用程序项目类型 带有DLL作为选项 当我调用本机方法时 出现此异常 Exception occurred during even
  • IntelliJ IDEA 创建的 JAR 文件无法运行

    我在 IntelliJ 中编写了一个跨越几个类的程序 当我在 IDE 中测试它时它运行良好 但是 每当我按照教程将项目制作成 jar 可执行文件时 它就不会运行 双击 out 文件夹中的文件时 该文件不会运行 并显示 无法启动 Java J
  • 使用 ANTLR 为 java 源代码生成抽象语法树

    如何使用 ANTLR 从 java src 代码生成 AST 有什么帮助吗 好的 步骤如下 前往ANTLR站点 http www antlr org 并下载最新版本 下载Java g和JavaTreeParser g文件来自here htt
  • java中删除字符串中的特殊字符?

    如何删除字符串中除 之外的特殊字符 现在我用 replaceAll w s 它删除了所有特殊字符 但我想保留 谁能告诉我我该怎么办 Use replaceAll w s 我所做的是将下划线和连字符添加到正则表达式中 我添加了一个 连字符之前
  • jdbc4.MySQLSyntaxErrorException:数据库中不存在表

    我正在使用 SpringBoot 开发一个网络应用程序 这是我的application properties文件来指定访问数据库的凭据 spring datasource driverClassName com mysql jdbc Dri
  • Clip 在 Java 中播放 WAV 文件时出现严重延迟

    我编写了一段代码来读取 WAV 文件 大小约为 80 mb 并播放该文件 问题是声音播放效果很差 极度滞后 你能告诉我有什么问题吗 这是我的代码 我称之为doPlayJframe 构造函数内的函数 private void doPlay f
  • 归并排序中的递归:两次递归调用

    private void mergesort int low int high line 1 if low lt high line 2 int middle low high 2 line 3 mergesort low middle l
  • 尝试使用 Ruby Java Bridge (RJB) gem 时出现错误“无法创建 Java VM”

    我正在尝试实现 Ruby Java Bridge RJB gem 来与 JVM 通信 以便我可以运行 Open NLP gem 我在 Windows 8 上安装并运行了 Java 所有迹象 至少我所知道的 都表明 Java 已安装并可运行
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • Java中未绑定通配符泛型的用途和要点是什么?

    我不明白未绑定通配符泛型有什么用 具有上限的绑定通配符泛型 stuff for Object item stuff System out println item Since PrintStream println 可以处理所有引用类型 通
  • Java - 不要用 bufferedwriter 覆盖

    我有一个程序可以将人员添加到数组列表中 我想做的是将这些人也添加到文本文件中 但程序会覆盖第一行 因此这些人会被删除 如何告诉编译器在下一个空闲行写入 import java io import java util import javax
  • 查看Jasper报告执行的SQL

    运行 Jasper 报表 其中 SQL 嵌入到报表文件 jrxml 中 时 是否可以看到执行的 SQL 理想情况下 我还想查看替换每个 P 占位符的值 Cheers Don JasperReports 使用 Jakarta Commons
  • KeyPressed 和 KeyTyped 混淆[重复]

    这个问题在这里已经有答案了 我搜索过之间的区别KeyPressedand KeyTyped事件 但我仍然不清楚 我发现的一件事是 Keypressed 比 KeyTyped 首先被触发 请澄清一下这些事件何时被准确触发 哪个适合用于哪个目的
  • 中断连接套接字

    我有一个 GUI 其中包含要连接的服务器列表 如果用户单击服务器 则会连接到该服务器 如果用户单击第二个服务器 它将断开第一个服务器的连接并连接到第二个服务器 每个新连接都在一个新线程中运行 以便程序可以执行其他任务 但是 如果用户在第一个
  • java8 Collectors.toMap() 限制?

    我正在尝试使用java8Collectors toMap on a Stream of ZipEntry 这可能不是最好的想法 因为在处理过程中可能会发生异常 但我想这应该是可能的 我现在收到一个我不明白的编译错误 我猜是类型推理引擎 这是
  • javax.persistence.Table.indexes()[Ljavax/persistence/Index 中的 NoSuchMethodError

    我有一个 Play Framework 应用程序 并且我was使用 Hibernate 4 2 5 Final 通过 Maven 依赖项管理器检索 我决定升级到 Hibernate 4 3 0 Final 成功重新编译我的应用程序并运行它

随机推荐

  • 图片像素、英寸、厘米之间的单位换算

    转自 http hi baidu com cjg501 blog item f040fc0898d5379f0b7b8244 html 今天朋友用photoshop处理图片时要把图片保存指定的大小 但她只对厘米要形像感 可是在软件里保存的图
  • Maven+Idea打jar包个人总结

    Maven Idea打jar包个人总结 文章目录 Maven Idea打jar包个人总结 1 前言 2 安装配置JDK 3 Maven安装和配置 3 1 下载安装maven 3 2 配置环境变量 3 3 修改maven配置文件并创建本地仓库
  • BigDecimal除法向上取整,保留 1 为小数(Java、MySQL各自写法)

    SQL写法 CEILING SUM hdd SEND OUT QTY hsl DEMAND QTY 1000 10 EXECUTE RATE Java写法 updateData getExecuteQty divide soLineQtyM
  • 阿里云实践 - HTML5断点播放m3u8视频(videojs)

    场景 HTML5页面需要通过
  • EMC问题之RE实验最优解

    EMC问题之RE实验最优解 RE实验中 最关键的可能也是最难的就是找到干扰源 进而确定是传导辐射还是空间辐射 选择对应的是一定要加屏蔽罩 哪怕环路面积很小 辐射能量还是很强 还是仅仅依靠滤波等就能解决问题 实验现象 在160MHz 80MH
  • shell中如何进行一段代码的注释

    在shell编程中 我们常常需要把一些语句注释掉 让它不执行 对单号或者少数几行shell脚本来说 在每行前面增加 符号就可以达到目的了 代码如下 cp a txt b txt mkdir p 1 2 4 2 4 6 echo ok 但如果
  • ARP欺骗和DNS劫持以及Wireshark分析

    一 实验目的 利用ettercap进行中间人攻击之ARP欺骗和DNS劫持 用Wireshark分析相关特征数据 提高对ettercap Wireshark的熟练度 同时也对中间人攻击有更加深入的认识 二 实验原理 常见的ARP欺骗方式有两种
  • 使用conda时出现Solving environment: failed with initial frozen solve. Retrying with flexible solve错误

    使用conda安装pytorch 出现了各种各样的错误 尝试了网上各种办法 最后我是这么解决的 首先添加镜像源 在终端运行以下代码 conda config add channels https mirrors tuna tsinghua
  • JDBC(数据库连接)

    JDBC 简介 什么是 JDBC JDBC 指 Java 数据库连接 是一种标准Java应用编程接口 JAVA API 用来连接 Java 编程语言和广泛的数据库 JDBC API 库包含下面提到的每个任务 都是与数据库相关的常用用法 制作
  • 学习开源项目NewBeeMall新蜂商城(1) - 初步了解与运行NewBeeMall

    文章目录 0 前言 1 NewBeeMall 新蜂商城简介 2 NewBeeMall项目配置与运行 2 1 配置MySQL数据库 2 2 配置图片资源 2 3 运行NewBeeMAll 3 NewBeeMall相关技术栈 3 1 项目原版技
  • 关于++与+=

    今天在模仿别人做购物车网页 本想用jquey的text 获取一件物品的数量 如 1 由于忽略了text 获取的是字符串 于是用了 1运算符 发现字符串也能用 输出为 11 看了模仿的网站发现他并不需要用到parseInt 函数来将字符串变为
  • 454. 4Sum II 解题记录

    题目描述 Given four lists A B C D of integer values compute how many tuples i j k l there are such that A i B j C k D l is z
  • MOSFET 导通条件

    MOSFET管是FET的一种 可以被制造为增强型或者耗尽型 P沟道或N沟道共四种类型 但实际应用的只有增强型的N沟道MOS管和增强型的P沟道MOS管 实际应用中 NMOS居多 如何分辨三个极 D极单独位于一边 而G极是第4PIN 剩下的3个
  • 支持IDE最新版!新一代报表工具FastReport VCL v6.7更新详情

    FastReport VCL是用于Delphi C Builder RAD Studio和Lazarus的报告和文档创建VCL库 它提供了可视化模板设计器 可以访问最受欢迎的数据源 报告引擎 预览 将过滤器导出为30多种格式 并可以部署到云
  • 激光条纹中心线提取算法总结和复现

    滤波 分割等预处理过程省略 输入图像为灰度图 激光条纹水平走向 目录 几何中心法 极值法 细化法 灰度重心法 法向质心法 Steger算法 几何中心法 检测出光条边界 l h 后 把两边界的中间线 l h 2作为激光条纹的中心线 inclu
  • Unity访问 FTP-SSL、FTP服务器(记录)

    1 ftps是基于ftp做了层加密 只记录ftps的访问 2 使用的工具 FluentFTP 由于直接导入unity访问文件会报安全句柄错误 因此需要以下操作 3 流程 下载FluentFTP 修改 cs文件 重新编译 dll 原因 Saf
  • 入门级详细USB移植教程——致正在为USB烦恼的朋友

    同上一篇MPU6050一样 我还是写一篇关于USB的帖子 在圈圈等玩USB的大神面前 我掌握的USB知识实在是九牛一毛 所以这篇帖子加上了入门级的修饰语 写这篇帖子主要是为了那些想快速开发USB的人 至于想深入了解USB协议 可以先学完我这
  • Access数据库注入详解

    一个人再冷酷无情 他曾经都单纯过 能有这样的结果 都是被逼的 渗透入坑学废集 前言 注入漏洞分析 网站分类 常见数据库 网站访问模型 漏洞成因 注入漏洞是怎么样形成的 常见的注入流程 注入危害 ACCESS数据库注入详解 ACCESS数据库
  • 【BZOJ】【P1816】【Cqoi2010】【扑克牌】【题解】【水题】

    传送门 http www lydsy com JudgeOnline problem php id 1816 一张图表示我wa了三次的心情 Code include
  • SpringBoot01--运行原理和自动装配原理

    SpringBoot01 一 是什么 二 SpringBoot优点 三 运行原理 四 Springboot注解 五 自动装配原理 三步 是什么 怎么做 为什么 一 是什么 1 Spring Boot是由Pivotal团队提供的全新框架 其设