首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring常用的注解详细介绍 原理分析,与实际案例

Spring常用的注解详细介绍 原理分析,与实际案例

原创
作者头像
用户6229308
发布2025-06-16 22:22:20
发布2025-06-16 22:22:20
6610
举报
文章被收录于专栏:springspring

@TOC

一、核心容器注解

1. @Component

作用:通用注解,标识类为Spring管理的组件

原理:被扫描的类会被注册为Spring容器中的Bean,基于ClassPathBeanDefinitionScanner实现组件扫描

示例:

代码语言:java
复制
@Component("myService")
public class MyService {
    public void execute() {
        System.out.println("Service executed");
    }
}

2. @Autowired

作用:自动注入依赖

原理:通过AutowiredAnnotationBeanPostProcessor处理器实现依赖装配

示例:

代码语言:java
复制
@Service
public class OrderService {
    // 字段注入
    @Autowired
    private PaymentService paymentService;
    
    // 构造器注入(推荐)
    @Autowired
    public OrderService(InventoryService inventoryService) {
        this.inventoryService = inventoryService;
    }
}

3. @Qualifier

作用:解决多个相同类型Bean的歧义性问题

原理:与@Autowired配合使用,指定具体的Bean名称

示例:

代码语言:java
复制
@Repository("jdbcUserDao")
public class JdbcUserDao implements UserDao { }

@Repository("jpaUserDao")
public class JpaUserDao implements UserDao { }

@Service
public class UserService {
    @Autowired
    @Qualifier("jpaUserDao") // 明确指定JPA实现
    private UserDao userDao;
}

4. @Configuration 和 @Bean

作用:Java配置类代替XML配置

原理:使用CGLIB增强配置类,确保@Bean方法的单例性

示例:

代码语言:java
复制
@Configuration
public class AppConfig {
    
    @Bean(name = "dataSource")
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        return ds;
    }
    
    @Bean
    public PlatformTransactionManager transactionManager(
        @Autowired DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

5. @Scope

作用:定义Bean的作用域

原理:通过ScopeMetadataResolver解析作用域信息

示例:

代码语言:java
复制
@Component
@Scope("prototype") // 每次请求创建新实例
public class ShoppingCart { }

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, 
       proxyMode = ScopedProxyMode.INTERFACES)
public class UserPreferences { } // 会话作用域

6. @Profile

作用:环境条件化配置

原理:基于Environment中的激活profile加载对应Bean

示例:

代码语言:java
复制
@Configuration
@Profile("development")
public class DevDatasourceConfig {
    @Bean
    public DataSource dataSource() {
        // 开发环境数据源
    }
}

@Configuration
@Profile("production")
public class ProdDatasourceConfig {
    @Bean
    public DataSource dataSource() {
        // 生产环境数据源
    }
}

7. @Value

作用:属性注入

原理:通过PropertySourcesPlaceholderConfigurer解析占位符

示例:

代码语言:java
复制
@Service
public class EmailService {
    
    @Value("${email.smtp.host}")
    private String smtpHost;
    
    @Value("${email.smtp.port:587}")
    private int smtpPort;
    
    @Value("#{systemProperties['user.name']}")
    private String systemUser;
}

二、Spring MVC注解

1. @Controller

作用:标记MVC控制器

原理:HandlerMapping检测并映射请求

代码语言:java
复制
@Controller
@RequestMapping("/products")
public class ProductController {
    
    @Autowired
    private ProductRepository repository;
    
    @GetMapping("/{id}")
    public String getProduct(@PathVariable Long id, Model model) {
        model.addAttribute("product", repository.findById(id));
        return "product-detail";
    }
}

2. @RestController

作用:@Controller + @ResponseBody的组合

代码语言:java
复制
@RestController
@RequestMapping("/api/products")
public class ProductApiController {
    
    @GetMapping("/{id}")
    public Product getProduct(@PathVariable Long id) {
        return repository.findById(id);
    }
}

3. 请求映射注解

类型:

  • @RequestMapping
  • @GetMapping
  • @PostMapping
  • @PutMapping
  • @PatchMapping
  • @DeleteMapping
代码语言:java
复制
@PostMapping(value = "/create", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Product> createProduct(
    @RequestBody Product product, 
    UriComponentsBuilder builder) {
    
    Product saved = repository.save(product);
    URI location = builder.path("/products/{id}")
                         .buildAndExpand(saved.getId()).toUri();
    
    return ResponseEntity.created(location).body(saved);
}

4. 参数绑定注解

常用:

  • @PathVariable:获取URL中的模板变量
  • @RequestParam:获取请求参数
  • @RequestBody:获取请求体内容
  • @RequestHeader:获取请求头
  • @CookieValue:获取Cookie值
代码语言:java
复制
@GetMapping("/search")
public List<Product> searchProducts(
    @RequestParam(value = "name", defaultValue = "") String name,
    @RequestParam("minPrice") double minPrice,
    @RequestParam("maxPrice") double maxPrice) {
    
    return repository.findByNameContainingAndPriceBetween(name, minPrice, maxPrice);
}

三、事务管理

@Transactional

作用:声明式事务管理

原理:基于AOP实现事务拦截,核心类为TransactionInterceptor

代码语言:java
复制
@Service
public class OrderService {
    
    @Transactional(
        propagation = Propagation.REQUIRED,
        isolation = Isolation.READ_COMMITTED,
        timeout = 30,
        rollbackFor = {PaymentException.class, InventoryException.class}
    )
    public Order createOrder(OrderRequest request) {
        // 多个数据库操作组成事务
        reduceInventory(request); 
        createPaymentRecord(request);
        createOrderRecord(request);
        return order;
    }
}

配置要求:

代码语言:java
复制
@Configuration
@EnableTransactionManagement // 启用注解驱动的事务管理
public class PersistenceConfig {
    
    @Bean
    public PlatformTransactionManager transactionManager(
        DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

四、AOP编程

1. 切面声明

代码语言:java
复制
@Aspect
@Component
public class LoggingAspect {
    
    // 定义切点(使用AspectJ表达式)
    @Pointcut("execution(* com.example.service.*.*(..))")
    public void serviceLayer() {}
    
    // Around通知:环绕目标方法
    @Around("serviceLayer()")
    public Object logExecutionTime(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = pjp.proceed(); // 执行目标方法
        long duration = System.currentTimeMillis() - start;
        System.out.println(pjp.getSignature() + " executed in " + duration + "ms");
        return result;
    }
    
    // AfterThrowing通知:异常处理
    @AfterThrowing(pointcut = "serviceLayer()", throwing = "ex")
    public void logException(JoinPoint jp, Exception ex) {
        System.err.println("Exception in " + jp.getSignature() + ": " + ex.getMessage());
    }
}

2. 启用AOP

代码语言:java
复制
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true) // 启用AspectJ代理
public class AopConfig {
    // 自动扫描@Aspect注解
}

五、Spring Boot扩展注解

1. @SpringBootApplication

组成:

  • @SpringBootConfiguration:继承自@Configuration
  • @EnableAutoConfiguration:启用自动配置
  • @ComponentScan:组件扫描
代码语言:java
复制
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2. @Conditional 家族

条件化配置示例:

代码语言:java
复制
@Configuration
public class FeatureConfig {
    
    // 仅当某个类在类路径中存在时创建Bean
    @Bean
    @ConditionalOnClass(name = "com.example.SpecialService")
    public FeatureService featureService() {
        return new FeatureServiceImpl();
    }
    
    // 仅当某个属性为true时创建Bean
    @Bean
    @ConditionalOnProperty(name = "features.analytics", havingValue = "true")
    public AnalyticsService analyticsService() {
        return new GoogleAnalytics();
    }
}

3. @Enable* 系列

代码语言:java
复制
// 启用缓存
@EnableCaching
// 启用定时任务
@EnableScheduling
// 启用异步执行
@EnableAsync
// 启用JPA仓库
@EnableJpaRepositories
// 启用实体管理器
@EntityScan("com.example.domain")
public class ApplicationConfig {}

六、高级功能注解

1. 事件监听

代码语言:java
复制
@Component
public class OrderEventListener {
    
    // 监听OrderCreatedEvent事件
    @EventListener
    public void handleOrderCreated(OrderCreatedEvent event) {
        System.out.println("Processing order: " + event.getOrder());
    }
    
    // 事务监听器
    @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
    public void handleAfterCommit(OrderCreatedEvent event) {
        // 仅在事务提交后执行
    }
}

2. 异步处理

代码语言:java
复制
@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {
    
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        executor.initialize();
        return executor;
    }
}

@Service
public class NotificationService {
    
    @Async
    public void sendEmail(String to, String content) {
        // 异步发送邮件
    }
}

3. 自定义注解

创建组合注解:

代码语言:java
复制
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 多个注解的组合
@Transactional(rollbackFor = Exception.class)
@Retryable(maxAttempts = 3, backoff = @Backoff(delay = 2000))
@MetricTime("serviceLayer")
public @interface BusinessTransaction {}

使用:

代码语言:java
复制
@Service
public class OrderService {
    
    @BusinessTransaction
    public Order processOrder(Order order) {
        // 同时具有事务、重试和监控功能
    }
}

七、注解原理深度解析

注解处理机制

  1. 组件扫描:
    • ClassPathScanningCandidateComponentProvider扫描类路径
    • 使用AnnotationTypeFilter检测标记注解
    • 注册BeanDefinition
  2. 依赖注入:
    • AutowiredAnnotationBeanPostProcessor处理注入
    • 解析字段、方法和构造器上的注解
    • 解决依赖并注入值
  3. AOP代理:
    • 创建代理对象(JDK动态代理或CGLIB)
    • AnnotationAwareAspectJAutoProxyCreator管理切面
  4. 事务管理:
    • 创建事务代理
    • 事务拦截器处理事务边界
    • PlatformTransactionManager管理实际事务

性能优化技巧

  1. 注解层级优化:
代码语言:java
复制
// 优先在类上声明注解
@Service
@Transactional
public class OrderService {
    // 避免在方法上重复声明
}
  1. 组件扫描优化:
代码语言:java
复制
@ComponentScan(
    basePackages = "com.example",
    excludeFilters = @ComponentScan.Filter(
        type = FilterType.REGEX, 
        pattern = ".*Test.*")
)
  1. 缓存注解配置:
代码语言:java
复制
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@Caching(
    cacheable = @Cacheable("users"),
    put = @CachePut(value = "users", key = "#result.id")
)
public @interface CacheUser {}

常见问题解决

  1. 循环依赖问题:
    • 使用setter注入代替构造器注入
    • 添加@Lazy注解延迟初始化
代码语言:java
复制
@Service
public class ServiceA {
    private final ServiceB serviceB;

    public ServiceA(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}
  1. 事务失效场景:
    • 确保异常类型正确配置:rollbackFor = Exception.class
    • 避免同一个类中非公开方法调用
    • 使用@EnableTransactionManagement(proxyTargetClass=true)
  2. AOP拦截限制:
    • 使用@EnableAspectJAutoProxy(exposeProxy = true)暴露代理
    • 在内部方法调用时使用 AopContext.currentProxy()
代码语言:java
复制
public void outerMethod() {
    innerMethod(); // AOP不会拦截
    ((MyService) AopContext.currentProxy()).innerMethod(); // 正确方式
}

掌握这些核心注解及其原理,能大幅提升Spring应用的开发效率和质量。建议在实际项目中结合Spring Boot使用,实现更为简洁高效的开发模式。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、核心容器注解
    • 1. @Component
    • 2. @Autowired
    • 3. @Qualifier
    • 4. @Configuration 和 @Bean
    • 5. @Scope
    • 6. @Profile
    • 7. @Value
  • 二、Spring MVC注解
    • 1. @Controller
    • 2. @RestController
    • 3. 请求映射注解
    • 4. 参数绑定注解
  • 三、事务管理
    • @Transactional
  • 四、AOP编程
    • 1. 切面声明
    • 2. 启用AOP
  • 五、Spring Boot扩展注解
    • 1. @SpringBootApplication
    • 2. @Conditional 家族
    • 3. @Enable* 系列
  • 六、高级功能注解
    • 1. 事件监听
    • 2. 异步处理
    • 3. 自定义注解
  • 七、注解原理深度解析
    • 注解处理机制
    • 性能优化技巧
    • 常见问题解决
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档