@configuration 用于标记一个类为配置类,表明该类将包含一个或多个 @Bean
方法,用于定义 Spring 容器中管理的 bean。
@Configuration 表示该类是 Spring 配置的一部分,通常代替传统的 XML 配置文件。使用该注解的类会被 Spring 容器处理,并允许在该类中定义和管理多个 bean。
主要作用:
标记配置类 :@Configuration
用于标识一个类是配置类,这个类中的方法通常会使用 @Bean
注解来定义 Spring 容器中需要管理的 bean。
替代 XML 配置 :它允许你通过 Java 代码配置 Spring 应用上下文,避免了传统 XML 配置的繁琐。
增强功能 :@Configuration
类默认会被 CGLIB 动态代理增强,使得在配置类中定义的 bean 能够进行更强的管理,例如支持方法级的 bean 定义。
@RequestBody
是 Spring Framework 中的一种注解,通常用于处理 HTTP 请求的正文(body)数据。它的主要作用是将请求中的数据自动绑定到 Java 对象上。
@RequestBody 用法: @RequestBody
注解用于方法参数上,表示从 HTTP 请求的 Body 部分提取数据并将其转换为 Java 对象。Spring 会根据请求的 Content-Type
和方法参数的类型,自动将请求内容转换为相应的对象。
示例: 假设我们有一个 User
类:
1 2 3 4 5 6 javaCopy Codepublic class User { private String name; private int age; }
然后在控制器方法中使用 @RequestBody
注解来处理传递的 JSON 数据:
1 2 3 4 5 6 7 8 javaCopy Code@RestController public class UserController { @PostMapping("/user") public String createUser(@RequestBody User user) { return "User received: " + user.getName() + ", Age: " + user.getAge(); } }
解释:
常见用途:
JSON 数据处理 :@RequestBody
是处理 JSON 请求的主要方式,Spring 会使用 HttpMessageConverter
(如 Jackson)来自动将 JSON 数据转换为 Java 对象。
处理复杂请求 :对于包含复杂嵌套结构的请求体(例如嵌套对象、数组等),@RequestBody
可以非常方便地将数据映射为相应的 Java 类。
需要注意的事项:
由于使用 @RequestBody
会自动解析请求体,因此它只能用于 POST
、PUT
、PATCH
等请求类型。
在使用 @RequestBody
时,通常需要客户端设置正确的 Content-Type
,如 application/json
。
@Autowired @Autowired
是 Spring Framework 中的一种注解,主要用于实现依赖注入(Dependency Injection)。它可以让 Spring 自动为你的类的字段、构造方法或 setter 方法注入所需的依赖对象。
用法和作用:
自动注入依赖 :@Autowired
注解使得 Spring 可以自动将符合要求的 Bean 注入到你的类中,而无需手动配置。Spring 会根据类型、名称或者构造函数来寻找匹配的 Bean 并进行注入。
主要的使用方式: 1. 字段注入 通过 @Autowired
注解在类的成员变量上,Spring 会自动为这个字段赋值。最常见的使用方式。
1 2 3 4 5 6 7 8 9 javaCopy Code@Component public class Car { @Autowired private Engine engine; // 自动注入 Engine 类型的 Bean public void start() { engine.run(); } }
在上面的例子中,Car
类依赖 Engine
类,通过 @Autowired
注解,Spring 会自动注入一个 Engine
类型的 Bean 到 Car
的 engine
字段。
2. 构造方法注入 @Autowired
也可以应用到构造方法上,Spring 会根据构造方法的参数类型来自动注入依赖的 Bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 javaCopy Code@Component public class Car { private final Engine engine; @Autowired public Car(Engine engine) { // 自动注入 Engine 类型的 Bean this.engine = engine; } public void start() { engine.run(); } }
这种方式是推荐的做法,特别是当依赖项为必需时,可以更好地控制依赖关系。
3. Setter 方法注入 你也可以将 @Autowired
放在 setter 方法上,Spring 会在创建对象后通过调用 setter 方法注入依赖。
1 2 3 4 5 6 7 8 9 10 11 12 13 javaCopy Code@Component public class Car { private Engine engine; @Autowired public void setEngine(Engine engine) { // 自动注入 Engine 类型的 Bean this.engine = engine; } public void start() { engine.run(); } }
这也是一种常见的依赖注入方式。
自动注入的原理:
Spring 会根据 @Autowired
注解标记的字段、构造函数或 setter 方法,查找匹配的 Bean 实例并注入。默认情况下,它是根据 类型 来进行匹配。
如果找到多个匹配的 Bean,且没有明确的标识,Spring 会抛出异常。在这种情况下,你可以使用 @Qualifier
来指定具体的 Bean。
例外和配置:
如果没有找到匹配的 Bean :如果没有符合要求的 Bean,Spring 会抛出异常,默认情况下是 NoSuchBeanDefinitionException
。如果你希望在没有匹配 Bean 时不报错,可以使用 @Autowired(required = false)
来设置为非必需的。
1 2 javaCopy Code@Autowired(required = false) private Engine engine; // 如果没有 Engine 类型的 Bean,Spring 不会抛出异常
多重 Bean 注入冲突 :如果 Spring 容器中存在多个同类型的 Bean,Spring 默认会抛出 NoUniqueBeanDefinitionException
。这时可以通过 @Qualifier
来明确指定要注入哪个 Bean:
1 2 3 javaCopy Code@Autowired @Qualifier("carEngine") // 明确指定注入哪个 Bean private Engine engine;
总结:
@Autowired
是 Spring 中用于实现自动依赖注入的注解。它可以用于字段、构造函数或 setter 方法上。
Spring 会根据 Bean 类型自动查找并注入依赖项。
使用 @Autowired
可以大大减少手动配置和管理 Bean 之间的依赖关系,提高代码的可维护性和可扩展性。
1. 组件相关注解
@Controller :用于修饰 MVC 中控制器层的组件。Spring Boot 中的组件扫描功能会识别此注解,并为被修饰的类实例化一个对象。它通常与@RequestMapping 一起使用。当 Spring MVC 收到请求时,会将其转发到指定路径的方法进行处理。
1 2 3 4 @Controller @RequestMapping("/user/admin") public class UserAdminController {}
@Service :通常用于修饰服务层的组件。声明一个对象时,会实例化该类对象并将其注入到 bean 容器中。
1 2 3 4 @Service public class UserService { }
@Repository :用于修饰数据访问对象(DAO)层的组件。DAO 层的组件专注于系统数据的处理,例如数据库中的数据。它们也会被组件扫描并生成实例化对象。
1 2 3 4 @Repository public interface RoleRepository extends JpaRepository <Role, Long> { }
@Component :一般指代组件。当组件难以分类时,可以使用此注解进行标记。其功能与@Service 类似。
1 2 3 4 @Component public class DemoHandler { }
2. 与 Bean 实例和生命周期相关的注解
@Bean :用于修饰方法,表示该方法将创建一个 Bean 实例,并由 Spring 容器进行管理。示例代码如下:
1 2 3 4 5 6 7 8 @Configuration public class AppConfig { @Bean public Uploader initFileUploader () { return new FileUploader (); } }
@Scope :用于声明 Spring Bean 实例的作用域。作用域如下:
singleton:单例模式。在 Spring 容器中实例是唯一的,这是 Spring 的默认实例作用域类型。
prototype:原型模式。每次使用时都会重新创建实例。
request:在同一请求中使用相同的实例,不同请求创建新的实例。
session:在同一会话中使用相同的实例,不同会话创建新的实例。
1 2 3 4 5 6 7 8 @Configuration public class RestTemplateConfig { @Bean @Scope("singleton") public RestTemplate restTemplate () { return new RestTemplate (); } }
@Primary :当存在同一对象的多个实例时,优先选择此实例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration @ComponentScan public class JavaConfig { @Bean("b1") @Primary B b1 () { return new B (); } @Bean("b2") B b2 () { return new B (); } }
@PostConstruct :用于修饰方法,在对象实例创建和依赖注入完成后执行,可用于初始化对象实例。
@PreDestroy :用于修饰方法,在对象实例即将被 Spring 容器移除时执行,可用于释放对象实例持有的资源。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class Demo { public Demo () { System.out.println("构造方法..." ); } public void init () { System.out.println("init..." ); } } @PostConstruct public void postConstruct () { System.out.println("postConstruct..." ); } @PreDestroy public void preDestroy () { System.out.println("preDestroy..." ); } public void destroy () { System.out.println("destroy..." ); }
输出:
1 2 3 4 5 构造方法... postConstruct... init... preDestroy... destroy...
3. 依赖注入注解
@Autowired :根据对象的类型自动注入依赖对象。默认情况下,它要求注入的对象实例必须存在。可以配置 required = false 来注入可能不存在的对象。
1 2 3 4 5 6 7 8 9 @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @Autowired(required = false) private UserConfig userConfig; }
@Resource :默认情况下,根据对象的名称自动注入依赖对象。如果要根据类型注入,可以设置属性 type = UmsAdminService.class。
1 2 3 4 5 6 @Controller @RequestMapping("/user") public class UserController { @Resource(name = "userServiceImpl") private UserService userService; }
@Qualifier :当存在同一类型的多个 bean 时,使用@Autowired 导入会导致错误,表示当前对象不唯一,Spring 不知道要导入哪个依赖。此时,我们可以使用@Qualifier 进行更细粒度的控制并选择其中一个实例。它通常与@Autowired 一起使用。示例如下:
1 2 3 @Autowired @Qualifier("deptService") private DeptService deptService;
4. SpringMVC 相关注解
@RequestMapping :提供路由信息,负责将 URL 映射到 Controller 中的指定函数。当用于方法上时,可以指定请求协议,如 GET、POST、PUT、DELETE 等。
@RequestBody :表示请求体的 Content - Type 必须是 application/json 格式的数据。接收到数据后,会自动将数据绑定到 Java 对象。
@ResponseBody :表示此方法的返回结果直接写入 HTTP 响应体。返回数据的格式为 application/json。 例如,如果请求参数是 json 格式,返回参数也是 json 格式,示例代码如下:
1 2 3 4 5 6 7 8 9 10 @Controller @RequestMapping("api") public class LoginController { @RequestMapping(value = "login", method = RequestMethod.POST) @ResponseBody public ResponseEntity login (@RequestBody UserLoginDTO request) { return new ResponseEntity (HttpStatus.OK); } }
@RestController :与@Controller 类似,用于注释控制器层组件。不同之处在于它是@ResponseBody 和@Controller 的组合。 即,当在类上使用@RestController 时,表示当前类中所有对外暴露的接口方法,返回数据的格式都是 application/json。示例代码如下:
1 2 3 4 5 6 7 8 9 @RestController @RequestMapping("/api") public class LoginController { @RequestMapping(value = "/login", method = RequestMethod.POST) public ResponseEntity login (@RequestBody UserLoginDTO request) { return new ResponseEntity (HttpStatus.OK); } }
@RequestParam :用于接收请求参数为表单类型的数据。通常用于方法的参数前面。示例代码如下:
1 2 3 4 5 6 7 8 @RequestMapping(value = "login", method = RequestMethod.POST) @ResponseBody public ResponseEntity login ( @RequestParam(value = "userName", required = true) String userName, @RequestParam(value = "userPwd", required = true) String userPwd) { return new ResponseEntity (HttpStatus.OK); }
@PathVariable :用于获取请求路径中的参数。通常用于 restful 风格的 API。示例代码如下:
1 2 3 4 5 6 @RequestMapping(value = "queryProduct/{id}", method = RequestMethod.POST) @ResponseBody public ResponseEntity queryProduct (@PathVariable("id") String id) { return new ResponseEntity (HttpStatus.OK); }
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping :除了@RequestMapping 能够指定请求方法外,还有一些其他注解可以用于注释接口路径请求。例如,当@GetMapping 用于方法上时,表示仅支持 get 请求方法。它等同于@RequestMapping(value = “/get”, method = RequestMethod.GET)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @GetMapping("get") public ResponseEntity get () { return new ResponseEntity (HttpStatus.OK); } @PostMapping("post") public ResponseEntity post () { return new ResponseEntity (HttpStatus.OK); } @PutMapping("put") public ResponseEntity put () { return new ResponseEntity (HttpStatus.OK); } @DeleteMapping("delete") public ResponseEntity delete () { return new ResponseEntity (HttpStatus.OK); }
5. 配置相关注解
@Configuration :表示声明一个基于 Java 的配置类。Spring Boot 提倡基于 Java 对象的配置,相当于以前在 xml 中配置 bean。例如,声明一个配置类 AppConfig,然后初始化一个 Uploader 对象。
1 2 3 4 5 6 7 @Configuration public class AppConfig { @Bean public Uploader initOSSUploader () { return new OSSUploader (); } }
@EnableAutoConfiguration :@EnableAutoConfiguration 可以帮助 Spring Boot 应用程序将所有符合条件的@Configuration 配置类加载到当前的 Spring Boot 中,创建与配置类对应的 Beans,并将 Bean 实体交给 IoC 容器管理。在某些场景下,如果我们想要避免某些配置类的扫描(包括避免一些第三方 jar 下的配置),可以这样处理。
1 2 3 4 5 6 7 @Configuration @EnableAutoConfiguration(exclude = { org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class }) public class AppConfig { }
@ComponentScan :注释哪些路径下的类需要被 Spring 扫描。用于自动发现和组装一些 Bean 对象。默认配置是扫描当前文件夹及子目录中的所有类。如果我们想要指定扫描某些包路径,可以这样处理。
1 @ComponentScan(basePackages = {"com.xxx.a", "com.xxx.b", "com.xxx.c"})
@SpringBootApplication :相当于使用了@Configuration、@EnableAutoConfiguration 和@ComponentScan 这三个注解。通常用于全局启动类。示例如下:
1 2 3 4 5 6 @SpringBootApplication public class PropertyApplication { public static void main (String[] args) { SpringApplication.run(PropertyApplication.class, args); } }
用这三个注解@configuration、@EnableAutoConfiguration 和@ComponentScan 替换@springBootApplication 也可以成功启动,@springBootApplication 只是简化了这三个注解。
@EnableTransactionManagement :表示启用事务支持,相当于 xml 配置方式中的 tx:annotation - driven/>。
1 2 3 4 5 6 7 @SpringBootApplication @EnableTransactionManagement public class PropertyApplication { public static void main (String[] args) { SpringApplication.run(PropertyApplication.class, args); } }
@ConfigurationProperties :用于批量注入外部配置,并以对象的形式导入具有指定前缀的配置。例如,这里我们在 application.yml 中指定前缀为 secure.ignored 的属性:
1 2 3 4 5 6 7 8 9 10 11 secure: ignored: urls: # 安全路径白名单 - /swagger-ui/ - /swagger-resources *.htm1 - / ** *.css - / **
然后,在 Java 类中定义一个 urls 属性,就可以导入配置文件中的属性。
1 2 3 4 5 6 7 @Getter @Setter @Configuration @ConfigurationProperties(prefix = "secure.ignored") public class IgnoreUrlsConfig { private List<String> urls = new ArrayList <>(); }
@Conditional :从 Spring 4 开始,@Conditional 注解可以用于有条件地加载 bean 对象。目前,在 Spring Boot 源代码中,@Condition 注解已经得到了广泛的扩展,用于实现智能自动配置,以满足各种使用场景。以下是一些常用的注解:
@ConditionalOnBean:当指定的 Bean 存在时,配置生效。
@ConditionalOnMissingBean:当指定的 Bean 不存在时,配置生效。
@ConditionalOnClass:当指定的类在类路径中存在时,配置生效。@ConditionalOnMissingClass:当指定的类在类路径中不存在时,配置生效。
@ConditionalOnExpression:当给定的 SpEL 表达式的计算结果为 true 时,配置生效。
@ConditionalOnProperty:当指定的配置属性具有确定的值且匹配时,配置生效。 具体应用案例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 @Configuration public class ConditionalConfig { @ConditionalOnBean(Test.class) @Bean public A createA () { return new A (); } @Conditional0nMissingBean(Test.class) @Bean public B createB () { return new B (); } @Conditional0nclass(Test.class) @Bean public C createC () { return new C (); } @Conditional0nMissingClass(Test.class) @Bean public D createD () { return new D (); } @Conditiona10nExpression("$ {enableConfig:false}") @Bean public E createE () { return new E (); } @Conditiona10nProperty(prefix = "filter", name = "loginilter", havingalue = "true") @Bean public F createF () { return new F (); } }
@Value :在任何 Spring 管理的 Bean 中,可以通过此注解获取从任何源配置的属性值。例如,在 application.properties 文件中,定义一个参数变量:
在任何 bean 实例内,可以通过@Value 注解注入参数并获取参数变量的值。
1 2 3 4 5 6 7 8 9 10 @RestController public class HelloController { @Value("${config.name}") private String configName; @GetMapping("config") public String config () { return JSON.toJSONString(configName); } }
@ConfigurationProperties :在每个类中使用@Value 获取属性配置值的做法实际上并不推荐。 在一般的企业项目开发中,不会使用这种混乱的写法,而且维护也很麻烦。通常,一次读取一个 Java 配置类,然后在需要的地方直接引用这个类进行使用,这样可以多次访问且便于维护。示例如下: 首先,在 application.properties 文件中定义参数变量。
1 config.name=demo_1 config.value=demo_value_1
然后,创建一个 Java 配置类并注入参数变量。
1 2 3 4 5 6 7 8 @Component @ConfigurationProperties(prefix = "config") public class Config { public String name; public String value; }
最后,在需要的地方,通过 ioc 注入 Config 对象。
@PropertySource :此注解用于读取我们自定义的配置文件。例如,要导入两个配置文件 test.properties 和 bussiness.properties,用法如下:
1 2 3 4 5 6 7 @SpringBootApplication @PropertySource(value = {"test.properties", "bussiness.properties"}) public class PropertyApplication { public static void main (String[] args) { SpringApplication.run(PropertyApplication.class, args); } }
@ImportResource :用于加载 xml 配置文件。例如,要导入自定义的 aaa.xml 文件,用法如下:
1 2 3 4 5 6 7 @ImportResource(locations = "classpath:aaa.xml") @SpringBootApplication public class PropertyApplication { public static void main (String[] args) { SpringApplication.run(PropertyApplication.class, args); } }
6. JPA 相关注解
@Entity 和@Table :表示这是一个实体类。这两个注解通常一起使用。但是,如果表名与实体类名相同,@Table 可以省略。
@Id :表示此属性字段对应数据库表中的主键字段。
@Column :表示此属性字段对应的数据库表中的列名。如果字段名与列名相同,可以省略。
@GeneratedValue :表示主键的生成策略。有以下四个选项:
AUTO:表示由程序控制,是默认选项。如果未设置,则为该选项。
IDENTITY:表示由数据库生成,使用数据库自动递增。Oracle 不支持此方法。
SEQUENCE:表示主键 ID 通过数据库序列生成。MySQL 不支持此方法。
TABLE:表示主键由指定数据库生成。此方法有利于数据库迁移。
@SequenceGenerator :用于定义生成主键的序列。需要与@GeneratedValue 一起使用才能生效。以 role 表为例,相应的注解配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Entity @Table(name = "role") @SequenceGenerator(name = "id_seq", sequenceName = "seq_repair", allocationSize = 1) public class Role implements Serializable { private static final long serialVersionUID = 1L ; @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "id_seq") private Long id; @Column(nullable = false) private String roleName; @Column(nullable = false) private String roleType; }
@Transient :表示此属性不映射到数据库表的字段。ORM 框架将忽略此属性。
1 2 3 @Column(nullable = false) @Transient private String lastTime;
**@Basic(fetch = FetchType.LAZY)**:用于某些属性上,可以实现懒加载的效果。即,当使用此字段时,才会加载此属性。如果配置为 fetch = FetchType.EAGER,则表示立即加载,这也是默认的加载方式!
1 2 3 @Column(nullable = false) @Basic(fetch = FetchType.LAZY) private String roleType;
@JoinColumn :用于注释表示表关系的字段。通常与@OneToOne 和@OneToMany 一起使用。例如:
1 2 3 4 5 6 7 8 9 @Entity @Table(name = "tb_login_log") public class LoginLog implements Serializable { @OneToOne @JoinColumn(name = "user_id") private User user; }
@OneToOne、@OneToMany 和@ManyToOne :这三个注解相当于 hibernate 配置文件中的一对一、一对多和多对一配置。例如,在以下客户地址表中,可以通过客户 ID 查询客户信息。
1 2 3 4 5 6 7 8 9 @Entity @Table(name = "address") public class AddressEO implements java .io.Serializable { @ManyToOne(cascade = {CascadeType.ALL}) @JoinColumn(name = "customer_id") private CustomerEO customer; }
7. 异常处理相关注解
@ControllerAdvice 和@ExceptionHandler :它们通常一起使用来处理全局异常。示例代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Slf4j @Configuration @ControllerAdvice public class GlobalExceptionConfig { private static final Integer GLOBAL_ERROR_CODE = 500 ; @ExceptionHandler(value = Exception.class) @ResponseBody public void exceptionHandler (HttpServletRequest request, HttpServletResponse response, Exception e) throws Exception { log.error("统一异常处理器:" , e); ResultMsg<Object> resultMsg = new ResultMsg <>(); resultMsg.setCode(GLOBAL_ERROR_CODE); if (e instanceof CommonException) { CommonException ex = (CommonException) e; if (ex.getErrCode()!= 0 ) { resultMsg.setCode(ex.getErrCode()); } resultMsg.setMsg(ex.getErrMsg()); } else { resultMsg.setMsg(CommonErrorMsg.SYSTEM_ERROR.getMessage()); } WebUtil.buildPrintWriter(response, resultMsg); } }
8. AOP 相关注解
@Aspect :用于定义一个切面。切面是通知和切入点的组合,它定义了在何时何地应用通知功能。
@Before :表示前置通知。通知方法将在目标方法调用之前执行。通知描述了切面要执行的工作以及执行的时间。
@After :表示后置通知。通知方法将在目标方法返回或抛出异常后执行。
@AfterReturning :表示返回通知。通知方法将在目标方法返回后执行。
@AfterThrowing :表示异常通知。通知方法将在目标方法抛出异常后执行。
@Around :表示环绕通知。通知方法将包装目标方法,并在目标方法调用前后执行自定义行为。
@Pointcut :定义切入点表达式,它定义了应用通知功能的范围。
@Order :用于定义组件的执行顺序。在 AOP 中,它指的是切面的执行顺序。value 属性的值越小,表示优先级越高。 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Aspect @Component @Order(1) public class WebLogAspect { private static final Logger LOGGER = LoggerFactory.getLogger(WebLogAspect.class); @Pointcut("execution(public * com.dylan.smith.web.controller.*.*(..))") public void webLog () { } @Before("webLog()") public void doBefore (JoinPoint joinPoint) throws Throwable { } @AfterReturning(value = "webLog()", returning = "ret") public void doAfterReturning (Object ret) throws Throwable { } @Around("webLog()") public Object doAround (ProceedingJoinPoint joinPoint) throws Throwable { WebLog webLog = new WebLog (); Object result = joinPoint.proceed(); LOGGER.info("{}" , JSONUtil.parse(webLog)); return result; } }
9. 测试相关注解
@Test :指定一个方法为测试方法。
@ActiveProfiles :一般应用于测试类,用于声明活动的 Spring 配置文件。例如,指定 application - dev.properties 配置文件。
@RunWith 和@SpringBootTest :一般应用于测试类,用于单元测试。示例如下:
1 2 3 4 5 6 7 8 9 @ActiveProfiles("dev") @RunWith(SpringRunner.class) @SpringBootTest public class TestJunit { @Test public void executeTask () { } }