乐趣区

关于java:面试必问Spring-bean-和-component-注解有什么区别

起源:blog.csdn.net/weixin_35544490/article/details/112143211

本文打算介绍几个不太容易说出其区别,或者用处的 Spring 注解,比方 @Component@Bean 的比拟,@ControllerAdvice 是如何解决自定义异样的等等。

Spring 中的一些注解

1. @Component 和 @Bean 的区别是什么?

  1. 作用对象不同:@Component 注解作用于类,而 @Bean 注解作用于办法、
  2. @Component 通常是通过门路扫描来主动侦测以及主动拆卸到 Spring 容器中(咱们能够应用 @ComponentScan 注解定义要扫描的门路从中找出标识了须要拆卸的类主动拆卸到 Spring 的 bean 容器中)。@Bean 注解通常是咱们在标有该注解的办法中定义产生这个 bean,@Bean 通知了 Spring 这是某个类的实例,当咱们须要用它的时候还给我。
  3. @Bean 注解比 @Component 注解的自定义性更强,而且很多中央咱们只能通过 @Bean 注解来注册 bean。比方当咱们援用第三方库中的类须要拆卸到 Spring 容器时,只能通过 @Bean 来实现。

@Bean 注解应用示例:

@Configuration
public class AppConfig {
    @Bean
public TransferService transferService() {return new TransferServiceImpl();
    }
}

@Component 注解应用示例:

@Component
public class ServiceImpl implements AService {....}

上面这个例子是通过 @Component 无奈实现的:

@Bean
public OneService getService(status) {case (status)  {
when 1:
return new serviceImpl1();
when 2:
return new serviceImpl2();
when 3:
return new serviceImpl3();}
}

2. Autowire 和 @Resource 的区别

  1. @Autowire@Resource都能够用来拆卸 bean,都能够用于字段或 setter 办法。
  2. @Autowire 默认按类型拆卸,默认状况下必须要求依赖对象必须存在,如果要容许 null 值,能够设置它的 required 属性为 false。
  3. @Resource 默认按名称拆卸,当找不到与名称匹配的 bean 时才依照类型进行拆卸。名称能够通过 name 属性指定,如果没有指定 name 属性,当注解写在字段上时,默认取字段名,当注解写在 setter 办法上时,默认取属性名进行拆卸。

留神:如果 name 属性一旦指定,就只会依照名称进行拆卸。

@Autowire@Qualifier 配合应用成果和 @Resource 一样:

@Autowired(required = false) @Qualifier("example")
private Example example;

@Resource(name = "example")
private Example example;

@Resource 拆卸程序

  1. 如果同时指定 name 和 type,则从容器中查找惟一匹配的 bean 拆卸,找不到则抛出异样;
  2. 如果指定 name 属性,则从容器中查找名称匹配的 bean 拆卸,找不到则抛出异样;
  3. 如果指定 type 属性,则从容器中查找类型惟一匹配的 bean 拆卸,找不到或者找到多个抛出异样;
  4. 如果不指定,则主动依照 byName 形式拆卸,如果没有匹配,则回退一个原始类型进行匹配,如果匹配则主动拆卸。

3. 将一个类申明为 Spring 的 bean 的注解有哪些?

  • @Component:通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不晓得属于哪个层,能够应用 @Component 注解标注。
  • @Repository:对应长久层即 Dao 层,次要用于数据库相干操作。
  • @Service:对应服务层,次要设计一些简单的逻辑,须要用到 Dao 层。
  • @Controller:对应 Spring MVC 管制层,次要用来承受用户申请并调用 Service 层返回数据给前端页面。
  • @Configuration:申明该类为一个配置类,能够在此类中申明一个或多个 @Bean 办法。

4. @Configuration:配置类注解

@Configuration 表明在一个类里能够申明一个或多个 @Bean 办法,并且能够由 Spring 容器解决,以便在运行时为这些 bean 生成 bean 定义和服务申请,例如:

@Configuration
public class AppConfig {

    @Bean
public MyBean myBean() {// instantiate, configure and return bean ...}
}

咱们能够通过 AnnotationConfigApplicationContext 来注册 @Configuration 类:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
MyBean myBean = ctx.getBean(MyBean.class);
// use myBean ...

另外也能够通过组件扫描 (component scanning) 来加载,@Configuration 应用 @Component 进行原注解,因而 @Configuration 类也能够被组件扫描到(特地是应用 XML 的 元素)。@Configuration 类不仅能够应用组件扫描进行疏导,还能够应用 @ComponentScan 注解自行配置组件扫描:

@Configuration
@ComponentScan("com.acme.app.services")
public class AppConfig {// various @Bean definitions ...}

应用 @Configuration 的束缚:

  • 配置类必须以类的形式提供(比方不能是由工厂办法返回的实例)。
  • 配置类必须是非 final 的。
  • 配置类必须是非本地的(即可能不在办法中申明),native 标注的办法。
  • 任何嵌套的配置类必须申明为 static。
  • @Bean 办法可能不会反过来创立更多的配置类。

除了独自应用 @Configuration 注解,咱们还能够联合一些内部的 bean 或者注解独特应用,比方 Environment API@PropertySource@Value@Profile 等等许多,这里就不做具体介绍了,更多的用法能够参看 Spring @Configuration 的相干文档。

5. @ControllerAdvice:解决全局异样利器

在 Spring 3.2 中,新增了 @ControllerAdvice@RestControllerAdvice@RestController 注解,能够用于定义 @ExceptionHandler@InitBinder@ModelAttribute,并利用到所有 @RequestMapping@PostMapping@GetMapping等这些 Controller 层的注解中。

举荐一个 Spring Boot 基础教程及实战示例:
https://github.com/javastacks…

默认状况下,@ControllerAdvice 中的办法利用于全局所有的 Controller。而应用选择器 annotations()basePackageClasses()basePackages() (或其别名 value())来定义更小范畴的指标 Controller 子集。如果申明了多个选择器,则利用 OR 逻辑,这意味着所选的控制器应匹配至多一个选择器。请留神,选择器查看是在运行时执行的,因而增加许多选择器可能会对性能产生负面影响并减少复杂性。

@ControllerAdvice 咱们最常应用的是联合 @ExceptionHandler 用于全局异样的解决。能够联合以下例子,咱们能够捕捉自定义的异样进行解决,并且能够自定义状态码返回:

@ControllerAdvice("com.developlee.errorhandle")
public class MyExceptionHandler {
    /**
     * 捕捉 CustomException
     * @param e
     * @return json 格局类型
     */
    @ResponseBody
    @ExceptionHandler({CustomException.class}) // 指定拦挡异样的类型
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 自定义浏览器返回状态码
    public Map>String, Object< customExceptionHandler(CustomException e) {Map&lt;String, Object&gt; map = new HashMap&lt;&gt;();
map.put("code", e.getCode());
map.put("msg", e.getMsg());
return map;
    }
}

更多信息能够参看 Spring @ControllerAdvice 的官网文档。

6. @Component, @Repository, @Service 的区别

@Component是一个通用的 Spring 容器治理的单例 bean 组件。而 @Repository, @Service, @Controller 就是针对不同的应用场景所采取的特定功能化的注解组件。

因而,当你的一个类被 @Component 所注解,那么就意味着同样能够用@Repository, @Service, @Controller 来代替它,同时这些注解会具备有更多的性能,而且性能各异。

最初,如果你不晓得要在我的项目的业务层采纳 @Service 还是 @Component 注解。那么,@Service是一个更好的抉择。

总结

以上简略介绍了几种 Spring 中的几个注解及代码示例,就我集体而言,均是平时用到且不容易了解的几个,或者容易疏忽的几个。当然,这篇文章并没有齐全介绍完,在今后还会持续补充欠缺。

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿(2021 最新版)

2. 别在再满屏的 if/ else 了,试试策略模式,真香!!

3. 卧槽!Java 中的 xx ≠ null 是什么新语法?

4.Spring Boot 2.5 重磅公布,光明模式太炸了!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

退出移动版