被各种注解搞晕了?那快来看看Spring Bean注解详解!

简介: 被各种注解搞晕了?那快来看看Spring Bean注解详解!

前言

本篇博客中,我们将会讨论用于声明不同类型 Beans 的几种最常用的 Spring Bean 注解。


众所周知,Spring 容器中有许多配置 Bean 的方法,我们既可以通过 XML 配置,也可以在配置类中使用 @Bean 注解来声明 Beans。此外,我们还可以使用 org.springframework.stereotype 包中的一个注解来对类进行标记,然后把其余工作交给组件扫描即可。


组件扫描

在 Spring 中,一旦我们启用了组件扫描, Spring 就会自动扫描包中的 Bean。


通过使用 @ComponentScan ,Spring 就会自动去扫描那些带有注释配置的类,我们可以使用 basePackages 或者 value 参数(两者是一样的,value 只不过是 basePackages 的另一种称呼)来直接指定我们所要扫描的包的名称,然后 Spring 就会去扫描我们指定包下所有带有 @Component 注解的类,然后将其自动注册为一个 Bean。


@Configuration
// 以下两者之一即可
@ComponentScan(basePackages = "com.cunyu.annotions")
// @ComponentScan(value = "com.cunyu.annotions")
class PetFactoryConfig{
    ……
}

此外,我们还可以使用 basePackageClasses 参数来指向基础包中的类。

@Configuration
@ComponentScan(basePackageClasses = PetFactoryConfig.class)
class PetFactoryConfig{
    ……
}

basePackages 和 basePackageClasses 两个参数都是数组类型的,所以在传参时我们可以为他们提供多个包。


而如果没有为 @ComponentScan 指定参数,那么 Spring 就只会扫描和 @ComponentScan 注释的类位于同一个包的带有 @Component 注解的其他类,然后将它们自动创建为一个 Bean。


@ComponentScan 充分利用了 Java 8 中的重复注解特性,因此我们能够用它来多次标记一个类:


@Configuration
@ComponentScan(basePackages = "com.cunyu.annotions")
@ComponentScan(basePackageClasses = PetFactoryConfig.class)
class PetFactoryConfig{
    ……
}

除开上面的方式来标记一个类外,我们还可以使用 @CompentScans 来将多个 @ComponentScan 包含起来,用于指定多个 @ComponentScan 配置。

@Configuration
@ComponentScans({
    @ComponentScan(basePackages = "com.cunyu.annotions"),
    @ComponentScan(basePackageClasses = PetFactoryConfig.class)
})
class PetFactoryConfig{
    ……
}

除开使用注解的方式来实现组件扫描之外,我们还可以通过配置 XML 来进行,只需要在我们的配置文件中如下内容即可:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans";
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
       xmlns:context="http://www.springframework.org/schema/context";
       xmlns:c="http://www.springframework.org/schema/c";
       xmlns:p="http://www.springframework.org/schema/p";
       xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd">;
    <context:component-scan base-package="com.cunyu.dao" />
    <context:component-scan base-package="com.cunyu.service" />
    <context:component-scan base-package="com.cunyu.controller" />
</beans>

context:component-scan 元素将实现同注解 @ComponentScan 一样的效果,即扫描 com.cunyu 包下所有带有 @Component 注解的类,并将它们注册创建为 Bean。


@Component

上一小节中我们讲了 @ComponentScan 会自动扫描组件过程中会去扫描那些带有 @Component 注解的类,并将其注册创建为 Bean,比如下面的例子:


@Component

public class Cat{

   ……

}


其中 Cat 类中带有 @Component 注解,当 Spring 自动扫描时,就会去扫描 Cat 这个类,并创建一个名为 cat 的 Bean 实例。


注意:默认情况下,使用 @ComponentScan 去扫描 @Component 注解的类,生成对应类的 Bean 实例时,Bean 实例具有与类名相同的名称,但不同的是 Bean 实例的首字母是小写,而一般类名首字母是大写。


@Component 是任意 Spring 管理组建的通用构造型,当组件不好归类时,一般使用该注解,又可以分为如下几个常用元注解:


@Repository:位于持久层,能将数据库操作跑出的原生异常转换为 Spring 持久层异常,用于标注数据访问组件,即 DAO 组件;

@Service:位于业务逻辑层,只是标注该类位于业务层逻辑;

@Configuration:用于定义配置类,可替换 XML 配置文件,被注解的类内部包含一个或多个被 @Bean 注解的方法,这些方法将会被 AnnotationConfigApplicaitonContext 或者 AnnotaionConfigWebApplicationContext 类扫描,并用于构建 Bean 定义,初始化 Spring 容器;

@Controller:属于 Spring MVC 的注解,进行前端请求的处理、转发、重定向;用于标注控制层组件;

它们是针对不同使用场景而采取的带有特定功能化的注解组件,其实质功能其实和 @Component 一样。因此,如果一个类被 @Component 注解了,那么就可以根据这个类的实际功能,利用 @Repository、@Service … 等代替,而且代替后的注解会具备更多的功能。


@Repository

DAO(Data Access Object,数据访问对象,为某种类型的数据库或其他持久性机制提供一个抽象接口的对象) 或者 Repository 类通常代表应用程序中的数据访问层,我们一般倾向于使用 @Repository 注解。


@Repository

public class PetRepository{

   ……

}


通过使用 @Repository 注解,它将启用自动持久化异常转换。此时,当我们使用一些持久化框架,比如 Hibernate、MyBatis……时,当带有 @Repository 注解的类在抛出本地异常时,就会自动将其转换为 Spring 中的 DataAccessException 的子类。


而要启动异常转换,我们就需要自己去声明我们 PersistenceExceptionTranslationPostProcessor 的实例,声明的方式可以分为注解性和 XML 配置型。但是一般而言,Spring 都会自动帮我们去完成这个过程,所以我们就不再需要自己去手动声明了。


注解型

@Bean

public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){

   return new PersistenceExceptionTranslationPostProcessor();

}


XML 配置型

<bean class="org.springframework.dao.annotion.PersistenceExceptionTranslationPostProcessor" />

1

@Service

对于应用程序中的业务逻辑,一般都是位于服务层,因此我们使用 @Service 注解一个类,来指明该类属于服务层。表示定义一个 Bean,自动根据所标注的组件实例化一个首字母为小写的 Bean。实例如下:


@Service

public class PetService{

   ……

}


上述代码中 PetService 类被标注为一个 Bean,其名称为 petServie。


@Configuration

一般用于配置类,而且还可以包含用 @Bean 所注解的 Bean 定义方法,实例如下:


@Configuration

public class PetFactoryConfig{

   @Bean

   public Dog dog(){

       return new Dog();

   }

}


既然说了使用 @Confgiuration 可以和 XML 配置文件互换,那么以上的配置类等价于如下配置:


<beans>

   <bean id="dog" class = "com.cunyu.dao.Dog"/>

</beans>


注意:使用 @Configuration 注解时,一般需要遵循如下原则:


@Configuration 注解的类不可以是 final 类型;

@Configuration 注解的类不可以是匿名类;

嵌套的 @Configuration 必须是静态类;

@Controller

@Controller 注解是一个类级别的注解,当把它用在类上时,表示该类在 Spring MVC 中充当控制器,该类将被 Spring 自动扫描,一般我们在该类中加入 @RequestMapping("…"),就可以直接使用浏览器来访问对应界面进行逻辑处理了。实例如下:


@Controller

public class PetController{

   @RequestMapping(value = "/hello", method = RequestMethod.GET)

   public String sayHello(){

 return "你好,村雨遥!";

   }

   ……

}


此时,当我们去浏览器中访问 localhost:8080/hello 时,页面中就会显示 你好,村雨遥! 这条信息。


注意,@Controller 注解的类下,我们又发现了 RequestMapping 注解,该注解主要 6 个属性,分别介绍如下:


value :用于指定浏览器指定的地址;

method,指定请求的 method 类型,一般有 GET、POST、PUT、DELETE,而现在我们一般使用对应的注解 @GetMapping、@PostMapping、@PutMapping、@DeleteMapping;

consumes:用于指定处理请求的提交内容类别(Content-Type),如 application/json、test/html;

produces:指定返回的内容类别;

params:指定 request 中必须包含某些引用数值时,才能让该方法处理;

headers:指定 request 中必须包含某些指定 header 值,才能让该方法处理请求;

原型注解及 AOP

当我们使用 Spring 原型注解时,可以十分容易地创建一个指向所有具有特定构造型的类的切入点。


比如我们如果想要衡量一个方法在 DAO 层中的执行时间,就可以充分利用 @Repository 注解的特点。


@Aspect
@Component
public class PerformanceAspect {
    @Pointcut("within(@org.springframework.stereotype.Repository *)")
    public void repositoryClassMethods() {};
    @Around("repositoryClassMethods()")
    public Object measureMethodExecutionTime(ProceedingJoinPoint joinPoint) 
      throws Throwable {
        long start = System.nanoTime();
        Object returnValue = joinPoint.proceed();
        long end = System.nanoTime();
        String methodName = joinPoint.getSignature().getName();
        System.out.println(
          "Execution of " + methodName + " took " + 
          TimeUnit.NANOSECONDS.toMillis(end - start) + " ms");
        return returnValue;
    }
}

以上实例中,我们创建了一个切入点,该切入点会去匹配带有 @Repository 注解的类中的所有方法。然后我们用 @Around 通知来定位切入点,并确定被拦截的方法调用的执行时间。通过使用这个方式,我们就可以轻松地给每个应用程序添加日志记录、性能管理、审计以及其他行为。


总结

好了,以上就主要介绍了 Spring 中的原型注释,并了解了它们各自所代表的意义。此外,还学习了如何使用组件扫描功能,从而告知 Spring 容器在何处能找到带有注解的类。


如果你有更多的见解,欢迎评论留言,一起交流呀!



目录
相关文章
|
3月前
|
缓存 监控 Java
SpringBoot @Scheduled 注解详解
使用`@Scheduled`注解实现方法周期性执行,支持固定间隔、延迟或Cron表达式触发,基于Spring Task,适用于日志清理、数据同步等定时任务场景。需启用`@EnableScheduling`,注意线程阻塞与分布式重复问题,推荐结合`@Async`异步处理,提升任务调度效率。
548 128
|
2月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
381 2
|
3月前
|
Java 测试技术 数据库
使用Spring的@Retryable注解进行自动重试
在现代软件开发中,容错性和弹性至关重要。Spring框架提供的`@Retryable`注解为处理瞬时故障提供了一种声明式、可配置的重试机制,使开发者能够以简洁的方式增强应用的自我恢复能力。本文深入解析了`@Retryable`的使用方法及其参数配置,并结合`@Recover`实现失败回退策略,帮助构建更健壮、可靠的应用程序。
368 1
使用Spring的@Retryable注解进行自动重试
|
3月前
|
XML Java 数据格式
常用SpringBoot注解汇总与用法说明
这些注解的使用和组合是Spring Boot快速开发和微服务实现的基础,通过它们,可以有效地指导Spring容器进行类发现、自动装配、配置、代理和管理等核心功能。开发者应当根据项目实际需求,运用这些注解来优化代码结构和服务逻辑。
296 12
|
3月前
|
传感器 Java 数据库
探索Spring Boot的@Conditional注解的上下文配置
Spring Boot 的 `@Conditional` 注解可根据不同条件动态控制 Bean 的加载,提升应用的灵活性与可配置性。本文深入解析其用法与优势,并结合实例展示如何通过自定义条件类实现环境适配的智能配置。
184 0
探索Spring Boot的@Conditional注解的上下文配置
|
3月前
|
智能设计 Java 测试技术
Spring中最大化@Lazy注解,实现资源高效利用
本文深入探讨了 Spring 框架中的 `@Lazy` 注解,介绍了其在资源管理和性能优化中的作用。通过延迟初始化 Bean,`@Lazy` 可显著提升应用启动速度,合理利用系统资源,并增强对 Bean 生命周期的控制。文章还分析了 `@Lazy` 的工作机制、使用场景、最佳实践以及常见陷阱与解决方案,帮助开发者更高效地构建可扩展、高性能的 Spring 应用程序。
133 0
Spring中最大化@Lazy注解,实现资源高效利用
|
3月前
|
Java 测试技术 编译器
@GrpcService使用注解在 Spring Boot 中开始使用 gRPC
本文介绍了如何在Spring Boot应用中集成gRPC框架,使用`@GrpcService`注解实现高效、可扩展的服务间通信。内容涵盖gRPC与Protocol Buffers的原理、环境配置、服务定义与实现、测试方法等,帮助开发者快速构建高性能的微服务系统。
584 0
|
Java 开发者 Spring
解析Spring中Bean的生命周期
解析Spring中Bean的生命周期
243 2
|
XML druid Java
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
Spring5系列学习文章分享---第二篇(IOC的bean管理factory+Bean作用域与生命周期+自动装配+基于注解管理+外部属性管理之druid)
197 0
|
Java 开发者 Spring
Spring bean的生命周期详解!
本文详细解析Spring Bean的生命周期及其核心概念,并深入源码分析。Spring Bean是Spring框架的核心,由容器管理其生命周期。从实例化到销毁,共经历十个阶段,包括属性赋值、接口回调、初始化及销毁等。通过剖析`BeanFactory`、`ApplicationContext`等关键接口与类,帮助你深入了解Spring Bean的管理机制。希望本文能助你更好地掌握Spring Bean生命周期。
1037 1