Spring注解开发【源码分析】

本文深入探讨了Spring框架的注解开发,涵盖了组件注册、生命周期、属性赋值、自动装配、AOP动态代理、声明式事务等方面。详细分析了如@ComponentScan、@Autowired、@Transactional等注解的工作原理,并从源码层面揭示了Bean的创建、初始化和销毁过程,以及AOP的实现机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、注册组件

@ComponentScan

扫描指定包下的组件。

String[] value():扫描基础包范围
Filter[] includeFilters():扫描并获取符合过滤规则的组件
Filter[] excludeFilters():扫描并排除符合过滤规则的组件
 - 过滤规则由@Filter定义

@Filter

定义扫描包的组件过滤规则。

FilterType type():过滤类型
 - ANNOTATION:按照是否标记注解
 - ASSIGNABLE_TYPE:按照类型,包括子类/实现类
 - CUSTOM:自定义过滤规则
Class<?>[] classes():type对应的类 

举例:扫描当前注解所在包下所有的类,只扫描出类上标注@Controller注解的类进行获取。

@ComponentScan(includeFilters = {
   
   
    @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)})

自定义组件过滤规则:

@Configuration
@ComponentScan(includeFilters = {
   
   
        @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyTypeFilter.class)})
public class MainConfig {
   
   
}

public class MyTypeFilter implements TypeFilter {
   
   

    /**
     * 过滤规则:获取到类名中包含 s 字符的类
     * @param metadataReader:读取到当前正在扫描类的信息
     * @param metadataReaderFactory:可以获取到其他任何类的信息
     */
    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
   
   
        // 获取到当前扫描类的信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        // 如果扫描类包含字符 s 就返回true 
        if (classMetadata.getClassName().contains("s")) {
   
   
            return true;
        }
        return false;
    }
}

@Scope

容器对象的作用范围,默认对象是单实例bean。

String value():指定作用范围的类型
 - prototype:多实例的,IOC容器启动并不会去调用方法创建对象在容器中,每次获取的时候
              才会调用方法创建对象。
 - singleton:单实例的,IOC容器启动会调用方法创建对象放到容器中。以后获取直接从容器
              中拿(map.get())- request:同一次请求创建一个实例。
 - session:同一个session创建一个实例。 

举例:创建一个Person对象,需要每次获取都是不同的实例对象。

@Bean
@Scope("prototype")
public Person person() {
   
   
    return Person();
}

@Lazy

懒加载,对于单实例bean在容器启动时不创建对象,而是在第一次使用(获取)bean时创建并初始化对象。

@Bean
@Lazy
public Person person() {
   
   
    return Person();
}

@Conditional

定义创建bean对象的条件。

Class<? extends Condition>[] value():指定实现Condition接口的类用于匹配创建条件

举例:如果在Linux操作系统下,创建Person bean对象。

/**
 * 使用@Conditional来定义,如果在Linux下就创建这个bean
 * @Conditional:定义创建bean对象的条件
 */
@Bean("linus")
@Conditional(value = LinuxCondition.class)
public Person person() {
   
   
    return new Person();
}

// 实现Condition来定义匹配条件
public class LinuxCondition implements Condition {
   
   
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
   
   
        // 通过上下文来获取程序运行环境
        Environment environment = context.getEnvironment();
        // 获取操作系统
        String property = environment.getProperty("os.name");
        if (property.contains("linux")) {
   
   
            return true;
        }
        return false;
    }
}

也可以将注解放在类上面,满足注解条件的类,这个类中的bean才会生效。

@Configuration
// 满足该条件,这个类的bean才会生效
@Conditional(val
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值