ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Spring 注解使用详解

Spring 注解使用详解 Spring 注解使用详解Spring 的注解体系覆盖了从 Bean 注册、依赖注入、AOP、事务到 Web 开发的方方面面。注解把配置信息直接写在代码上让开发和维护都更直观。本文按功能分类逐一说明常用注解的用法、适用场景和底层机制。一、注解生效的底层机制Spring 处理注解主要依赖两个扩展点BeanPostProcessor在 Bean 初始化前后介入处理Autowired、Value、PostConstruct等注解。AutowiredAnnotationBeanPostProcessor负责依赖注入CommonAnnotationBeanPostProcessor负责Resource、PostConstruct、PreDestroy。BeanFactoryPostProcessor在 Bean 实例化之前介入处理ComponentScan、Configuration、Bean等注解。ConfigurationClassPostProcessor负责解析配置类生成 BeanDefinition。注解本身不会“自动生效”是这些后置处理器在容器启动时扫描并执行对应逻辑。二、声明 Bean 的注解1. Component 及其派生注解注解语义特殊功能Component通用组件无Service业务层无语义清晰Repository数据访问层异常转换ControllerWeb 控制层视图解析RestControllerREST 控制器直接返回 JSONConfiguration配置类CGLIB 代理ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}RepositorypublicclassUserDaoImplimplementsUserDao{AutowiredprivateJdbcTemplatejdbcTemplate;}Bean 名称默认是类名首字母小写也可以显式指定Service(userService)。2. Bean标注在Configuration类的方法上把返回值注册为 Bean。适合第三方类或需要复杂初始化逻辑的对象。ConfigurationpublicclassAppConfig{BeanpublicDataSourcedataSource(){HikariDataSourcedsnewHikariDataSource();ds.setJdbcUrl(jdbc:mysql://localhost:3306/mydb);returnds;}BeanpublicJdbcTemplatejdbcTemplate(DataSourcedataSource){returnnewJdbcTemplate(dataSource);}}Bean方法参数会自动从容器注入。Bean(initMethod init, destroyMethod cleanup)可以指定初始化和销毁方法。三、依赖注入注解1. Autowired按类型自动注入可以标注在字段、构造方法、Setter 方法上。// 构造器注入推荐ServicepublicclassUserService{privatefinalUserDaouserDao;publicUserService(UserDaouserDao){this.userDaouserDao;}}// 字段注入ServicepublicclassUserService{AutowiredprivateUserDaouserDao;}required false允许依赖为 null。构造器注入是 Spring 官方推荐的方式保证依赖不可变且完全就绪。2. Qualifier同类型有多个 Bean 时按名称指定ServicepublicclassOrderService{AutowiredQualifier(aliPayService)privatePaymentServicepaymentService;}3. Primary同类型多 Bean 时标记首选ServicePrimarypublicclassAliPayServiceimplementsPaymentService{}Qualifier优先级高于Primary。4. Value注入简单类型和配置值ComponentpublicclassAppConfig{Value(${app.name})privateStringappName;Value(${app.timeout:30})privateinttimeout;}5. ResourceJSR-250 标准默认按名称注入ServicepublicclassUserService{Resource(nameuserDaoImpl)privateUserDaouserDao;}与Autowired的区别Autowired默认按类型Resource默认按名称Autowired支持required false和构造器注入Resource不支持。四、配置与扫描注解1. ComponentScan指定扫描包路径ConfigurationComponentScan(com.example)publicclassAppConfig{}2. Import导入其他配置类ConfigurationImport({DatabaseConfig.class,RedisConfig.class})publicclassAppConfig{}3. PropertySource加载自定义 properties 文件ConfigurationPropertySource(classpath:custom.properties)publicclassAppConfig{Value(${custom.value})privateStringvalue;}4. ConfigurationProperties批量绑定配置到对象ComponentConfigurationProperties(prefixapp)GetterSetterpublicclassAppProperties{privateStringname;privateinttimeout;privateListStringservers;}五、条件化与 Profile 注解1. Conditional根据条件决定是否注册 BeanBeanConditional(WindowsCondition.class)publicFileServicewindowsFileService(){returnnewWindowsFileService();}2. Spring Boot 条件注解注解条件ConditionalOnClassclasspath 存在指定类ConditionalOnMissingBean容器中不存在指定 BeanConditionalOnProperty配置属性满足条件ConditionalOnWebApplication是 Web 应用BeanConditionalOnMissingBeanpublicObjectMapperobjectMapper(){returnnewObjectMapper();}3. Profile按环境激活ConfigurationProfile(dev)publicclassDevConfig{}ConfigurationProfile(prod)publicclassProdConfig{}六、AOP 注解1. 开启 AOPConfigurationEnableAspectJAutoProxypublicclassAopConfig{}Spring Boot 中引入spring-boot-starter-aop后自动生效。2. 定义切面AspectComponentpublicclassLoggingAspect{Pointcut(execution(* com.example.service.*.*(..)))publicvoidserviceLayer(){}Before(serviceLayer())publicvoidbefore(JoinPointjp){System.out.println(执行前jp.getSignature().getName());}AfterReturning(pointcutserviceLayer(),returningresult)publicvoidafterReturning(JoinPointjp,Objectresult){System.out.println(返回result);}AfterThrowing(pointcutserviceLayer(),throwingex)publicvoidafterThrowing(JoinPointjp,Exceptionex){System.out.println(异常ex.getMessage());}Around(serviceLayer())publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{longstartSystem.currentTimeMillis();Objectresultpjp.proceed();System.out.println(耗时(System.currentTimeMillis()-start)ms);returnresult;}}七、事务注解ServicepublicclassOrderService{Transactional(rollbackForException.class,propagationPropagation.REQUIRED,isolationIsolation.READ_COMMITTED,timeout30)publicvoidcreateOrder(Orderorder){orderDao.save(order);inventoryDao.decrease(order.getProductId(),order.getQuantity());}}需要EnableTransactionManagementSpring Boot 自动配置。注意Transactional在同一个类内部调用不生效必须通过代理调用。八、Web 注解1. 请求映射RestControllerRequestMapping(/api/users)publicclassUserController{GetMapping(/{id})publicUsergetUser(PathVariableLongid){returnuserService.getById(id);}PostMappingpublicUsercreate(RequestBodyValidUseruser){returnuserService.save(user);}GetMappingpublicListUserlist(RequestParam(requiredfalse)Stringname){returnuserService.findByName(name);}}2. 全局异常处理RestControllerAdvicepublicclassGlobalExceptionHandler{ExceptionHandler(BusinessException.class)publicResponseEntityErrorResponsehandleBusiness(BusinessExceptione){returnResponseEntity.badRequest().body(newErrorResponse(e.getMessage()));}}九、测试注解SpringBootTestclassUserServiceTest{AutowiredprivateUserServiceuserService;MockBeanprivateUserDaouserDao;TestvoidtestGetUser(){when(userDao.findById(1L)).thenReturn(newUser(1L,张三));UseruseruserService.getById(1L);assertEquals(张三,user.getName());}}常用测试注解SpringBootTest、WebMvcTest、DataJpaTest、MybatisTest、MockBean、SpyBean、TestPropertySource。十、其他常用注解注解作用Async异步执行方法需EnableAsyncScheduled定时任务需EnableSchedulingCacheable缓存方法结果需EnableCachingCacheEvict清除缓存EventListener事件监听Order控制 Bean 加载顺序Lazy延迟初始化Scope指定作用域AsyncpublicCompletableFutureStringsendEmail(Stringto){...}Scheduled(cron0 0 2 * * ?)publicvoiddailyReport(){...}Cacheable(valueusers,key#id)publicUsergetUser(Longid){...}十一、注解使用最佳实践按层选择语义注解Controller 用RestControllerService 用ServiceDao 用Repository。优先使用构造器注入保证依赖不可变和完整。第三方类无法加注解时用ConfigurationBean注册。多环境配置用Profile避免运行时 if-else。提供默认实现时用ConditionalOnMissingBean允许用户覆盖。事务注解放在 Service 层注意内部调用失效问题。AOP 切面只处理真正的横切关注点避免滥用导致调试困难。测试中使用MockBean隔离外部依赖用切片测试代替完整SpringBootTest提升速度。十二、总结分类核心注解声明 BeanComponent、Service、Repository、Controller、RestController、Configuration、Bean依赖注入Autowired、Qualifier、Primary、Value、Resource配置与扫描ComponentScan、Import、PropertySource、ConfigurationProperties条件与 ProfileConditional、ConditionalOnXxx、ProfileAOPAspect、Pointcut、Before、After、Around事务TransactionalWebRequestMapping、GetMapping、PostMapping、RequestParam、PathVariable、RequestBody、RestControllerAdvice测试SpringBootTest、MockBean、WebMvcTest其他Async、Scheduled、Cacheable、EventListenerSpring 注解体系庞大但逻辑清晰声明 Bean 靠Component系列和Bean注入依赖靠Autowired系列扩展功能靠EnableXxx和条件注解。掌握这些注解的语义、生效机制和适用场景就能在开发中灵活组合写出简洁且易维护的 Spring 应用。
返回列表