Spring框架新注解与最佳实践

Bean作用域注解

@Scope注解深度解析

@Scope注解用于定义Bean的作用范围,是Spring容器管理Bean生命周期的重要机制。在Spring 5.x版本中,作用域类型扩展到六种:

  1. singleton(默认)
  2. prototype
  3. request
  4. session
  5. application
  6. websocket
@Configuration
public class AppConfig {
    @Bean
    @Scope("prototype")
    public TaskExecutor taskExecutor() {
        return new SimpleAsyncTaskExecutor();
    }
}

原型模式Bean的创建流程:

  1. 容器初始化时不创建实例
  2. 每次getBean()调用时
  3. 调用BeanPostProcessor的postProcessBeforeInitialization
  4. 执行@PostConstruct方法
  5. 调用InitializingBean的afterPropertiesSet
  6. 调用自定义init-method
  7. BeanPostProcessor的postProcessAfterInitialization

作用域代理模式

当短生命周期作用域Bean注入长生命周期Bean时,必须使用代理:

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, 
       proxyMode = ScopedProxyMode.TARGET_CLASS)
public UserPreferences userPreferences() {
    return new UserPreferences();
}
代理模式 适用场景 实现原理
TARGET_CLASS 类代理 CGLIB动态代理
INTERFACES 接口代理 JDK动态代理
NO 默认值 不创建代理

延迟加载机制

@Lazy注解实现原理

@Configuration
public class LazyConfig {
    
    @Bean
    @Lazy
    public HeavyResource heavyResource() {
        System.out.println("HeavyResource初始化...");
        return new HeavyResource();
    }
}

延迟加载的触发时机:

  1. ApplicationContext.getBean()
  2. @Autowired自动注入
  3. 通过ObjectProvider获取

延迟加载与代理模式

Spring通过动态代理实现延迟加载机制,核心逻辑位于LazyScope:

public class LazyScope implements Scope {
    public Object get(String name, ObjectFactory<?> objectFactory) {
        return new LazyObjectProxy(objectFactory);
    }
    
    private static class LazyObjectProxy implements Serializable {
        private final ObjectFactory<?> objectFactory;
        private volatile Object target;
        
        public Object get() {
            if (target == null) {
                synchronized (this) {
                    if (target == null) {
                        target = objectFactory.getObject();
                    }
                }
            }
            return target;
        }
    }
}

条件化配置注解

@Conditional底层架构

条件注解的核心接口:

public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

Spring内置条件实现类:

  1. OnClassCondition
  2. OnBeanCondition
  3. OnWebApplicationCondition
  4. OnPropertyCondition

自定义条件实现

实现操作系统判断条件:

public class OScondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Environment env = context.getEnvironment();
        String os = env.getProperty("os.name");
        return os != null && os.contains("Windows");
    }
}

组合条件配置示例:

@Configuration
public class SystemConfig {
    
    @Bean
    @Conditional(WindowsCondition.class)
    public CommandService windowsCmd() {
        return new WindowsCommandService();
    }
    
    @Bean
    @Conditional(LinuxCondition.class)
    public CommandService linuxCmd() {
        return new LinuxCommandService();
    }
}

环境配置注解

@Profile实现原理

Spring 4.0之后@Profile基于@Conditional实现:

@Retention(RetentionPolicy.RUNTIME)
@Conditional(ProfileCondition.class)
public @interface Profile {
    String[] value();
}

class ProfileCondition implements Condition {
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
        Environment env = context.getEnvironment();
        for (Object value : attrs.get("value")) {
            if (env.acceptsProfiles(((String[]) value))) {
                return true;
            }
        }
        return false;
    }
}

多环境配置示例:

# application-dev.properties
spring.datasource.url=jdbc:mysql://dev-db:3306/test

# application-prod.properties 
spring.datasource.url=jdbc:mysql://prod-db:3306/prod

激活方式:

  1. spring.profiles.active=dev
  2. JVM参数:-Dspring.profiles.active=prod
  3. 环境变量:export SPRING_PROFILES_ACTIVE=dev

依赖处理注解

@DependsOn高级用法

解决初始化顺序问题:

@Configuration
public class InitSequenceConfig {
    
    @Bean
    @DependsOn({"cacheManager", "configLoader"})
    public ServiceCoordinator serviceCoordinator() {
        return new ServiceCoordinator();
    }
    
    @Bean
    public CacheManager cacheManager() {
        return new EhCacheManager();
    }
    
    @Bean
    public ConfigLoader configLoader() {
        return new RemoteConfigLoader();
    }
}

初始化顺序控制流程:

  1. configLoader实例化
  2. cacheManager实例化
  3. serviceCoordinator实例化
  4. configLoader初始化方法执行
  5. cacheManager初始化方法执行
  6. serviceCoordinator初始化方法执行

自动装配注解

@Primary与@Qualifier

解决自动装配歧义性:

@Configuration
public class DataSourceConfig {
    
    @Bean
    @Primary
    public DataSource mainDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean
    @Qualifier("backup")
    public DataSource backupDataSource() {
        return DataSourceBuilder.create()
               .url("jdbc:mysql://backup-db:3306/backup")
               .build();
    }
}

@Service
public class DataService {
    
    @Autowired
    private DataSource primaryDataSource;
    
    @Autowired
    @Qualifier("backup")
    private DataSource backupDataSource;
}

装配优先级:

  1. @Qualifier指定名称
  2. @Primary标注的Bean
  3. 变量名称匹配Bean名称
  4. 类型唯一Bean

注解性能优化

注解处理优化策略

  1. 使用@Indexed加速组件扫描
@Indexed
@Component
public class FastComponent {}
  1. 合理配置@ComponentScan
@Configuration
@ComponentScan(
    basePackages = "com.example.main",
    excludeFilters = @Filter(type = FilterType.REGEX, 
    pattern = "com.example.test.*")
)
public class OptimizedScanConfig {}
  1. 启用Lite模式
@Configuration(proxyBeanMethods = false)
public class LiteModeConfig {
    @Bean
    public ServiceBean serviceBean() {
        return new ServiceBean(repositoryBean());
    }
    
    @Bean
    public RepositoryBean repositoryBean() {
        return new RepositoryBean();
    }
}

性能对比测试数据:

配置方式 启动时间 内存占用
全注解模式 3200ms 480MB
Lite模式 2100ms 320MB
XML配置 2800ms 410MB

注解安全实践

敏感配置加密

结合@Value与解密处理器:

@Configuration
public class SecureConfig {
    
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfig() {
        PropertySourcesPlaceholderConfigurer configurer 
            = new PropertySourcesPlaceholderConfigurer();
        configurer.setLocation(new ClassPathResource("secure.properties"));
        configurer.setPropertyResolver(new EncryptedPropertyResolver());
        return configurer;
    }
    
    @Service
    public class SecureService {
        @Value("${db.password}")
        private String dbPassword;
    }
}

自定义属性解析器:

public class EncryptedPropertyResolver implements PropertyResolver {
    private static final String ENC_PREFIX = "ENC(";
    private static final String ENC_SUFFIX = ")";
    
    @Override
    public String getProperty(String key) {
        String value = // 原始属性获取
        if (value.startsWith(ENC_PREFIX) && value.endsWith(ENC_SUFFIX)) {
            return decrypt(value.substring(4, value.length()-1));
        }
        return value;
    }
    
    private String decrypt(String ciphertext) {
        // AES解密实现
    }
}

注解调试技巧

注解元数据追踪

查看注解的元数据信息:

public class AnnotationDebugger implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        String[] beanNames = beanFactory.getBeanDefinitionNames();
        for (String name : beanNames) {
            BeanDefinition definition = beanFactory.getBeanDefinition(name);
            if (definition.getSource() instanceof AnnotatedTypeMetadata) {
                AnnotatedTypeMetadata metadata = (AnnotatedTypeMetadata) definition.getSource();
                Set<String> annTypes = metadata.getAnnotationTypes();
                annTypes.forEach(annType -> {
                    Map<String, Object> attrs = metadata.getAnnotationAttributes(annType);
                    System.out.println("Bean: " + name);
                    System.out.println("Annotation: " + annType);
                    System.out.println("Attributes: " + attrs);
                });
            }
        }
    }
}

调试输出示例:

Bean: dataSource
Annotation: org.springframework.context.annotation.Primary
Attributes: {value=true}

Bean: taskScheduler
Annotation: org.springframework.scheduling.annotation.EnableScheduling
Attributes: {}
正文到此结束
评论插件初始化中...
Loading...