什么是spring注入?
spring注入是什么意思_代码敲上天.的博客-CSDN博客
属性注入
这是大家最熟悉的一种方式了。
通过在Bean类中直接定义需要注入的Bean实例的字段,并在XML或注解中指定需要注入的Bean实例,容器在创建Bean实例时自动将Bean实例赋值给该字段,从而实现属性注入。
比如上面的name为asa ,age为11111 ,会把该属性直接注入到此应用中。
在 IDEA 里边,使用属性注入,会有一个警告:不推荐属性注入!
属性注入与其他注入方式相比之下则有一些缺点,比如:
依赖不明确:通过属性注入,可能出现一些Bean依赖关系不明确的情况,导致代码可读性降低。
空指针异常:属性注入可能会导致一些Bean属性为空,从而导致空指针异常。
难于排查问题:由于属性注入是在实例化后才进行的,因此可能出现在运行时才能发现的问题,增加了排查问题的难度。
set注入
构造器注入
spring 注入与自动装配的区别
Spring的“注入”和“自动装配”都是用于将对象之间的依赖关系管理起来的技术,但它们有一些不同之处。
定义
“注入”是将一个对象作为参数传递给另一个对象的过程,使得被传递对象成为接受对象的一个属性或者方法参数。在Spring中,这个过程是通过在容器中定义Bean并将它们作为依赖关系来实现的。
“自动装配”是一个自动化的过程,它通过扫描Spring容器中的Bean来确定它们之间的依赖关系,并将它们自动连接起来。这个过程是由Spring容器完成的,无需手动配置。
使用
在使用上,“注入”是手动设置对象之间的依赖关系,通常需要在代码中显式地指定注入哪个对象,如使用@Autowired注解进行属性注入,或者在XML配置文件中使用<property>标签进行属性注入。
“自动装配”是自动完成对象之间的依赖关系,不需要手动配置。可以通过在Spring容器中使用@Component、@Service、@Repository等注解标识Bean,使得Spring自动扫描并装配这些Bean。
灵活性
“注入”提供了更大的灵活性,因为它允许您手动指定对象之间的依赖关系,并且可以使用任何可用的Spring配置技术,如XML配置文件、Java配置类、注解等。这使得您可以更精细地控制对象之间的依赖关系。
“自动装配”则更加方便,因为它无需手动配置,可以自动完成对象之间的依赖关系。这在大型项目中特别有用,因为它可以减少手动配置的复杂性和错误的可能性。
什么是自动装配
@Bean和@Autowired有什么区别。
1、@Bean的注解就是替代我们之前配置spring的XML文件里面的的,毕竟按照配置文件的方式,在Java文件上用写代码写个bean,然后再去XML文件通过注册,来回操作太麻烦,直接在当前用到的直接写。
2、@Autowired自动装配指的就是使用将 Spring 容器中的 bean 自动的和我们需要这个 bean 的类组装在一起。
自动装配(Autowired)是Spring框架中一种自动化配置Bean之间依赖关系的技术。它通过扫描Spring容器中已经定义好的Bean,自动将相互依赖的Bean连接起来,从而避免了手动编写繁琐的配置文件。
举个例子,假设我们有以下的两个类:
public class UserService {
private UserDao userDao;
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public void saveUser(User user) {
userDao.save(user);
}
}
public class UserDao {
public void save(User user) {
//保存用户数据到数据库
}
}
在传统的Spring配置中,我们需要在XML配置文件中手动将UserService和UserDao的Bean进行关联:
<bean id="userDao" class="com.example.UserDao" />
<bean id="userService" class="com.example.UserService">
<constructor-arg ref="userDao" />
</bean>
但是,如果我们在UserService的构造方法上使用@Autowired注解进行自动装配,Spring将会自动在容器中查找类型为UserDao的Bean,并将它注入到UserService中,无需手动编写XML配置文件:
public class UserService {
@Autowired
private UserDao userDao;
public void saveUser(User user) {
userDao.save(user);
}
}
这样,当Spring容器启动时,它会自动扫描包中的所有类,发现UserService和UserDao的Bean,自动将它们关联起来,从而实现自动装配的效果。
spring 注入 是谁注入谁?
在Spring中,依赖注入(DI)是容器自动将一个Bean的依赖关系注入到另一个Bean中,因此通常被称为"控制反转"(IoC)。
spring ioC
spring ioc 就是bean 管理吗
是的,Spring IoC (Inversion of Control,控制反转) 是一种通过依赖注入的方式来管理对象的技术,其中 Spring 容器负责创建和管理应用程序中的对象,这些对象被称为 Spring Bean。Spring IoC 容器在启动时,会根据配置文件中的信息创建应用程序中需要使用的对象,并在需要的时候将这些对象注入到其他对象中,从而实现了对象之间的解耦。
在 Spring 中,我们通过配置文件或者注解来告诉容器需要创建哪些对象以及这些对象之间的依赖关系,然后容器会根据这些信息创建对象并将它们注入到其他对象中。这种方式可以提高应用程序的可维护性和可测试性,因为我们可以更容易地管理和替换对象,并且减少了对象之间的耦合度。
spring的bean管理的方式
在Spring框架中,有多种管理Bean的方式。下面列举了其中几种常见的方式:
XML配置文件:使用XML配置文件,将需要管理的Bean定义在配置文件中,使用容器读取配置文件并管理Bean的生命周期、依赖关系等。
注解:使用注解(如@Component、@Service、@Repository等)标记需要管理的Bean,Spring容器会自动扫描并将这些Bean纳入管理。
Java配置类:使用Java类来进行Bean的配置,通过在配置类上使用@Configuration注解,定义Bean的创建、依赖关系等,并通过在类中定义@Bean方法来创建Bean实例。
自动扫描:Spring容器可以通过自动扫描的方式,自动将指定包路径下的Bean纳入管理。这种方式需要在配置文件或Java配置类中进行配置。
Spring Boot的自动配置:在Spring Boot中,可以使用自动配置(auto-configuration)的方式,自动配置应用所需要的Bean,简化了应用的配置过程。Spring Boot会根据应用的依赖关系,自动选择合适的配置方案。
不同的管理方式有不同的适用场景和优缺点,开发者可以根据实际需要进行选择。通常,使用注解和Java配置类的方式相对更为简便和灵活,而XML配置文件则更加灵活和可读性更强。而自动扫描和自动配置则可以极大地减少开发者的配置工作,提高开发效率。
spring单测怎么写?
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyServiceTest {
@Autowired
GiteaInterface giteaInterface;
@Test
public void testMyService() {
try {
giteaInterface.pull();
} catch (Exception e) {
e.printStackTrace();
}
}
}
写单元测试时只需要使用@RunWith(SpringRunner.class)注解,以便JUnit能够运行Spring的测试框架,并使用@MockBean来模拟一些组件的行为。因为单元测试的目的是测试一个类或一个方法的功能是否正常,不需要启动完整的应用程序上下文。
而当需要进行集成测试时,我们则可以使用@SpringBootTest来启动完整的应用程序上下文,比如使用了
@Autowired
GiteaInterface giteaInterface;
则需要把@SpringBootTest也加上。
spring的代理是什么?
使用Spring代理的方式有两种:
基于接口的代理(JDK动态代理)在这种代理方式下,Spring会为实现了Service接口的ServiceImpl类创建一个代理类,并在代理类中添加事务处理的代码。当其他类通过Service接口调用ServiceImpl的方法时,实际上调用的是代理类的方法,从而实现了事务的自动处理。
基于类的代理(CGLIB代理)如果ServiceImpl没有实现Service接口,那么Spring就会使用CGLIB代理来为ServiceImpl创建代理类。CGLIB代理的原理是在运行时创建一个继承了ServiceImpl的子类,并在子类中添加事务处理的代码。当其他类通过ServiceImpl类调用方法时,实际上调用的是子类的方法,从而实现了事务的自动处理。
Java动态代理是基于接口的,通过Java的反射机制动态生成代理类,而CGLIB动态代理则是通过继承被代理类来生成代理类。
spring 多线程
spring 统一异常处理
在Spring中(controller 、service、dao 都可以直接抛出 必须是指定的异常),可以使用@ControllerAdvice和@ExceptionHandler注释来统一处理异常。@ControllerAdvice是一个用于定义全局控制器通知的注释,可以捕获应用程序中的任何异常并将其处理为合适的响应。
以下是一个简单的例子,展示了如何使用@ControllerAdvice和@ExceptionHandler注释来处理应用程序中的异常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleException(Exception ex) {
ErrorResponse errorResponse = new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFoundException(ResourceNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse(HttpStatus.NOT_FOUND.value(), ex.getMessage());
return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}
}
在上面的示例中,我们定义了一个全局异常处理程序,该程序捕获应用程序中的所有异常,并将其转换为适当的错误响应。我们还定义了一个特定类型的异常处理程序,用于捕获ResourceNotFoundException并将其转换为404错误响应。
注意,ErrorResponse是一个自定义类,用于包装错误响应。在这个例子中,我们将HTTP状态码和错误消息传递给构造函数,以便在处理异常时使用它们。
最后,我们在异常处理程序中使用ResponseEntity类来返回错误响应。ResponseEntity是一个Spring类,用于封装HTTP响应。我们可以使用它来指定响应状态码、响应正文和响应头。在这个例子中,我们返回一个ErrorResponse对象和适当的HTTP状态码。
异常处理规则
比如下面的shell执行异常被 pull 方法内部catch住了,这样别人不知道。就要主动抛出来
int pull = icodeOpenApiClient.pull(icodePullReqDTO);
if (pull != 0) {
FileUtils.deleteDirectory(homeFolder);
throw new DevHubException(ServiceCodeEnum.CODE_REPOSITORY_PULL_INVALID, "代码拉取失败");
}
// build
String buildScript = buildTaskDTO.getBuildEntry();
String buildCmd = " cd " + homePath + " && sh " + buildScript;
int build = ShellUtils.runShell(buildCmd);
if (build != 0) {
FileUtils.deleteDirectory(homeFolder);
throw new DevHubException(ServiceCodeEnum.BUILD_CONFIG_ARGUMENT_INVALID, "执行编译脚本失败");
}
spring 在日志中打印唯一请求id.
在 Spring 中生成唯一的 request id 可以通过拦截器(Interceptor)来实现。拦截器是一种机制,可以在请求被处理前或处理后,对请求或响应进行一些处理,比如记录日志、鉴权等。
我们可以定义一个拦截器,在拦截器中生成一个唯一的 request id,并将其保存在当前请求的上下文中(比如使用 ThreadLocal),然后在后续的请求处理中,可以使用这个 request id 来记录日志,从而实现唯一的 request id。
以下是一个简单的示例:
public class RequestIdInterceptor implements HandlerInterceptor {
private static final ThreadLocal<String> requestIdHolder = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String requestId = UUID.randomUUID().toString();
requestIdHolder.set(requestId);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
// 清理 request id
requestIdHolder.remove();
}
public static String getRequestId() {
return requestIdHolder.get();
}
}
在上面的示例中,我们定义了一个 RequestIdInterceptor 拦截器,在 preHandle 方法中生成一个唯一的 request id 并保存在 ThreadLocal 中,在 afterCompletion 方法中清理 request id。
然后我们可以在需要记录日志的地方获取当前的 request id,比如:
String requestId = RequestIdInterceptor.getRequestId();
logger.info("request id: {}, message: {}", requestId, message);
这样就可以在日志中记录唯一的 request id 了。注意,以上示例只是一个简单的示例,实际应用中还需要考虑并发情况和异常处理等。
本地线程
/**
* 线程用户信息变量,保存用户Id
*/
private static ThreadLocal<UserInfoDTO> userLocal = new TransmittableThreadLocal<>();
/**
* 线程用户sessionId
*/
private static ThreadLocal<String> sessionIdLocal = new TransmittableThreadLocal<>();
/**
* 请求IP地址
*/
private static ThreadLocal<String> requestIpLocal = new TransmittableThreadLocal<>();
springboot 怎么创建session
如果您正在使用基于Web的应用程序,则可以使用Servlet API中的HttpServletRequest对象来创建session。以下是一些创建和访问session的示例代码:
// 获取HttpServletRequest对象
public String createSession(HttpServletRequest request) {
// 创建一个新的session
HttpSession session = request.getSession();
// 将数据添加到session中
session.setAttribute("username", "john");
// 返回视图
return "index";
}
// 访问session中的数据
public String getSessionData(HttpServletRequest request) {
// 获取session
HttpSession session = request.getSession();
// 获取session中的数据
String username = (String) session.getAttribute("username");
// 返回视图
return "index";
}
HttpSession session = request.getSession();
这句话就创建了一个session,并且会自动给前端一个叫jessionid的cookie。
spring 注解
spring注解原理
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
String value() default "";
int count() default 0;
}
@MyAnnotation(value = "myValue", count = 10)
public class MyClass {
}
public class AnnotationDemo {
public static void main(String[] args) throws NoSuchMethodException {
MyClass obj = new MyClass();
// 获取类上的MyAnnotation注解
MyAnnotation classAnnotation = obj.getClass().getAnnotation(MyAnnotation.class);
System.out.println("classAnnotation value: " + classAnnotation.value());
System.out.println("classAnnotation count: " + classAnnotation.count());
// 获取value方法上的MyAnnotation注解
Method method = obj.getClass().getMethod("value");
MyAnnotation methodAnnotation = method.getAnnotation(MyAnnotation.class);
System.out.println("methodAnnotation value: " + methodAnnotation.value());
System.out.println("methodAnnotation count: " + methodAnnotation.count());
}
}
在 Spring 中,通过反射机制来读取注解的值。具体实现可以参考 org.springframework.core.annotation.AnnotationUtils 类,该类中有很多方法用于读取注解的值,比如 getAnnotationAttributes、findAnnotation 等等。这些方法会将注解上的各个属性及其对应的值读取出来,并以一个 Map 的形式返回。
Spring 还提供了许多工具类和注解处理器,可以帮助我们更方便地使用和处理注解,比如 @Autowired、@Value 等注解的处理器,以及 AnnotationConfigApplicationContext、@Configuration 等工具类。在 Spring 源代码中,可以看到这些工具类和处理器的具体实现。
写一个自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
/**
* 功能
*
* @return
*/
String title() default "";
/**
* 是否打印入参和结果 默认不打印
* @return
*/
boolean printParam() default false;
}
@Aspect
@Component
public class LogAspect {
/**
* controller层、service层,打印日志
*/
@Around("@annotation(commonLog)")
public void logAround(ProceedingJoinPoint pjp, Log commonLog) throws Throwable {
// get MethodName
String className = pjp.getTarget().getClass().getName();
String methodName = StringUtil.combineStr(className, DOT, pjp.getSignature().getName());
// 方法业务 这里 获取到注解中的值
String title = commonLog.title();
boolean printParam = commonLog.printParam();
String methodStartLog = String.format("business:[%s]. begin execute method: [%s]. userName: [%s]."
, title, methodName, userName);
if (printParam) {
Object[] args = pjp.getArgs();
methodStartLog = methodStartLog + String.format(" param: [%s].", JsonUtil.serialize(args));
}
// 打印日志
log.info(methodStartLog);
return ret;
}
}
每次请求都会进行打印。
常用注解
注解 | 解释 |
@Controller | 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上。 |
@Service | 组合注解(组合了@Component注解),应用在service层(业务逻辑层) |
@Reponsitory | 组合注解(组合了@Component注解),应用在dao层(数据访问层) |
@Component | 表示一个带注释的类是一个“组件”,成为Spring管理的Bean。当使用基于注解的配置和类路径扫描时,这些类被视为自动检测的候选对象。同时@Component还是一个元注解。 |
@Autowired | Spring提供的工具(由Spring的依赖注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自动注入。) |
@Resource | JSR-250提供的注解 |
@Inject | JSR-330提供的注解 |
@Configuration | 声明当前类是一个配置类(相当于一个Spring配置的xml文件) |
@ComponentScan | 自动扫描指定包下所有使用@Service,@Component,@Controller,@Repository的类并注册 |
@Bean | 注解在方法上,声明当前方法的返回值为一个Bean。返回的Bean对应的类中可以定义init()方法和destroy()方法,然后在@Bean(initMethod=”init”,destroyMethod=”destroy”)定义,在构造之后执行init,在销毁之前执行destroy。 |
@Aspect | 声明一个切面(就是说这是一个额外功能) |
@After | 后置建言(advice),在原方法前执行。 |
@Before | 前置建言(advice),在原方法后执行。 |
@Around | 环绕建言(advice),在原方法执行前执行,在原方法执行后再执行(@Around可以实现其他两种advice) |
@PointCut | 声明切点,即定义拦截规则,确定有哪些方法会被切入 |
@Transactional | 声明事务(一般默认配置即可满足要求,当然也可以自定义) |
@Cacheable | 声明数据缓存 |
@EnableAspectJAutoProxy | 开启Spring对AspectJ的支持 |
@Value | 值得注入。经常与Sping EL表达式语言一起使用,注入普通字符,系统属性,表达式运算结果,其他Bean的属性,文件内容,网址请求内容,配置文件属性值等等 |
@PropertySource | 指定文件地址。提供了一种方便的、声明性的机制,用于向Spring的环境添加PropertySource。与@configuration类一起使用。 |
@PostConstruct | 标注在方法上,该方法在构造函数执行完成之后执行。 |
@PreDestroy | 标注在方法上,该方法在对象销毁之前执行。 |
@Profile | 表示当一个或多个指定的文件是活动的时,一个组件是有资格注册的。使用@Profile注解类或者方法,达到在不同情况下选择实例化不同的Bean。@Profile(“dev”)表示为dev时实例化。 |
@EnableAsync | 开启异步任务支持。注解在配置类上。 |
@Async | 注解在方法上标示这是一个异步方法,在类上标示这个类所有的方法都是异步方法。 |
@EnableScheduling | 注解在配置类上,开启对计划任务的支持。 |
@Scheduled | 注解在方法上,声明该方法是计划任务。支持多种类型的计划任务:cron,fixDelay,fixRate |
@Conditional | 根据满足某一特定条件创建特定的Bean |
@Enable* | 通过简单的@Enable来开启一项功能的支持。所有@Enable注解都有一个@Import注解,@Import是用来导入配置类的,这也就意味着这些自动开启的实现其实是导入了一些自动配置的Bean(1.直接导入配置类2.依据条件选择配置类3.动态注册配置类) |
@RunWith | 这个是Junit的注解,springboot集成了junit。一般在测试类里使用:@RunWith(SpringJUnit4ClassRunner.class) — SpringJUnit4ClassRunner在JUnit环境下提供Sprng TestContext Framework的功能 |
@ContextConfiguration | 用来加载配置ApplicationContext,其中classes属性用来加载配置类:@ContextConfiguration(classes = {TestConfig.class(自定义的一个配置类)}) |
@ActiveProfiles | 用来声明活动的profile–@ActiveProfiles(“prod”(这个prod定义在配置类中)) |
@EnableWebMvc | 用在配置类上,开启SpringMvc的Mvc的一些默认配置:如ViewResolver,MessageConverter等。同时在自己定制SpringMvc的相关配置时需要做到两点:1.配置类继承WebMvcConfigurerAdapter类2.就是必须使用这个@EnableWebMvc注解。 |
@RequestMapping | 用来映射web请求(访问路径和参数),处理类和方法的。可以注解在类和方法上,注解在方法上的@RequestMapping路径会继承注解在类上的路径。同时支持Serlvet的request和response作为参数,也支持对request和response的媒体类型进行配置。其中有value(路径),produces(定义返回的媒体类型和字符集),method(指定请求方式)等属性。 |
@ResponseBody | 将返回值放在response体内。返回的是数据而不是页面 |
@RequestBody | 允许request的参数在request体中,而不是在直接链接在地址的后面。此注解放置在参数前。 |
@PathVariable | 放置在参数前,用来接受路径参数。 |
@RestController | 组合注解,组合了@Controller和@ResponseBody,当我们只开发一个和页面交互数据的控制层的时候可以使用此注解。 |
@ControllerAdvice | 用在类上,声明一个控制器建言,它也组合了@Component注解,会自动注册为Spring的Bean。 |
@ExceptionHandler | 用在方法上定义全局处理,通过他的value属性可以过滤拦截的条件:@ExceptionHandler(value=Exception.class)–表示拦截所有的Exception。 |
@ModelAttribute | 将键值对添加到全局,所有注解了@RequestMapping的方法可获得次键值对(就是在请求到达之前,往model里addAttribute一对name-value而已)。 |
@InitBinder | 通过@InitBinder注解定制WebDataBinder(用在方法上,方法有一个WebDataBinder作为参数,用WebDataBinder在方法内定制数据绑定,例如可以忽略request传过来的参数Id等)。 |
@WebAppConfiguration | 一般用在测试上,注解在类上,用来声明加载的ApplicationContext是一个WebApplicationContext。他的属性指定的是Web资源的位置,默认为src/main/webapp,我们可以修改为:@WebAppConfiguration(“src/main/resources”)。 |
@EnableAutoConfiguration | 此注释自动载入应用程序所需的所有Bean——这依赖于Spring Boot在类路径中的查找。该注解组合了@Import注解,@Import注解导入了EnableAutoCofigurationImportSelector类,它使用SpringFactoriesLoader.loaderFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包。而spring.factories里声明了有哪些自动配置。 |
@SpingBootApplication | SpringBoot的核心注解,主要目的是开启自动配置。它也是一个组合注解,主要组合了@Configurer,@EnableAutoConfiguration(核心)和@ComponentScan。可以通过@SpringBootApplication(exclude={想要关闭的自动配置的类名.class})来关闭特定的自动配置。 |
@ImportResource | 虽然Spring提倡零配置,但是还是提供了对xml文件的支持,这个注解就是用来加载xml配置的。例:@ImportResource({“classpath |
@ConfigurationProperties | 将properties属性与一个Bean及其属性相关联,从而实现类型安全的配置。例:@ConfigurationProperties(prefix=”authot”,locations={“classpath |
@ConditionalOnBean | 条件注解。当容器里有指定Bean的条件下。 |
@ConditionalOnClass | 条件注解。当类路径下有指定的类的条件下。 |
@ConditionalOnExpression | 条件注解。基于SpEL表达式作为判断条件。 |
@ConditionalOnJava | 条件注解。基于JVM版本作为判断条件。 |
@ConditionalOnJndi | 条件注解。在JNDI存在的条件下查找指定的位置。 |
@ConditionalOnMissingBean | 条件注解。当容器里没有指定Bean的情况下。 |
@ConditionalOnMissingClass | 条件注解。当类路径下没有指定的类的情况下。 |
@ConditionalOnNotWebApplication | 条件注解。当前项目不是web项目的条件下。 |
@ConditionalOnResource | 条件注解。类路径是否有指定的值。 |
@ConditionalOnSingleCandidate | 条件注解。当指定Bean在容器中只有一个,后者虽然有多个但是指定首选的Bean。 |
@ConditionalOnWebApplication | 条件注解。当前项目是web项目的情况下。 |
@EnableConfigurationProperties | 注解在类上,声明开启属性注入,使用@Autowired注入。例:@EnableConfigurationProperties(HttpEncodingProperties.class)。 |
@AutoConfigureAfter | 在指定的自动配置类之后再配置。例:@AutoConfigureAfter(WebMvcAutoConfiguration.class) |
spring 微服务 与dubbo 都能实现分布式的需求,他们有什么差别
spring cloud 是什么
分布式事务
idea debug 快捷键
F7 | 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果该方法体还有方法,则不会进入该内嵌的方法中 |
F8 | 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则不进入当前方法体内 |
F9 | 在 Debug 模式下,恢复程序运行,但是如果该断点下面代码还有断点则停在下一个断点上 |
Alt + F8(MAC是option+F8) | 在 Debug 的状态下,选中对象,弹出可输入计算表达式调试框,查看该输入内容的调试结果 |
Ctrl + F8 | 在 Debug 模式下,设置光标当前行为断点,如果当前已经是断点则去掉断点 |
Shift + F7 | 在 Debug 模式下,智能步入。断点所在行上有多个方法调用,会弹出进入哪个方法 |
Shift + F8 | 在 Debug 模式下,跳出,表现出来的效果跟 F9 一样 |
Ctrl + Shift + F8 | 在 Debug 模式下,指定断点进入条件 |
Alt + Shift + F7 | 在 Debug 模式下,进入下一步,如果当前行断点是一个方法,则进入当前方法体内,如果方法体还有方法,则会进入该内嵌的方法中,依此循环进入 |