Spring源码分析

Spring源码分析,第1张

Spring源码分析 Spring 架构原理图

核心注解

@Bean

使用 @Bean + @Configuration 的形式可以替代 xml 配置文件的形式

@import

@import:指示要导入的一个或多个组件类

Spring 提供了很多方式来定义 bean 的信息,包括 xml 配置文件,注解,网络,磁盘等,通过资源加载器加载这些资源中的 bean 信息到 BeanDefinitionRegistrar 中,BeanDefinitionRegistrar 就相当于所有 bean 信息的档案馆,无论是 xml 还是注解方式定义的 bean 信息,最近进入的都是 BeanDefinitionRegistrar,在 BeanDefinitionRegistrar 中定义的只是 bean 的类型、名称信息,bean 的属性值等信息不在 BeanDefinitionRegistrar 中定义

在 @import 中可以直接传入 bean 的 class,也可以传入 BeanDefinitionRegistry 加载其中所有的 bean 定义信息,使用如下

@import({Person.class, Config.MyBeanDefinitionRegistry.class})
static class MyBeanDefinitionRegistry implements importBeanDefinitionRegistrar {
	@Override
    public void registerBeanDefinitions(Annotationmetadata importingClassmetadata, BeanDefinitionRegistry registry) 	{
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
        
        // 手动定义 bean 信息
        rootBeanDefinition.setBeanClass(Person.class);
        registry.registerBeanDefinition("person01", rootBeanDefinition);
    }
}
@Lookup

当单例的组件中需要依赖非单例的组件时,使用此注解实现,注意,一旦使用此注解,则对应的非单实例属性不能使用 @Autowired 注入且 @Lookup 需要标注在对应属性的 getXxx() 方法上,使用如下

public class MainTest {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        Person p1 = context.getBean(Person.class);
        Person p2 = context.getBean(Person.class);

        System.out.println(p1.getCat() == p2.getCat()); // false
    }
}

Cat 类

@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE) // 原型模式,非单例
@Component
public class Cat {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Person 依赖 Cat

package com.dhj.demo.bean;

import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;


@Component
public class Person {
    private String name;

    private Cat cat;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                '}';
    }
    
    @Lookup
    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }
Spring 容器类关系图

Spring 核心接口

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5481713.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-12
下一篇2022-12-12

发表评论

登录后才能评论

评论列表(0条)

    保存