欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

框架源码解析,第一篇Spring5.0源码解析(一)

程序员文章站 2022-06-15 20:09:33
...

1.spring bean id 不允许重复重复启动会报错

Spring的核心就是IOC和AOP,那你能说是什么是IOC吗?

IOC是控制反转是一个管理Bean的容器,常常伴随的还有DI依赖注入,@Autowired就是DI依赖注入,控制外层的@Controller就是通过这个注解来把这个controller类通过扫包的方式交给IOC容器来管理,创建的过程是默认是单例的恶汉模式,创建完毕之后是放在单例池之中,也就是spring三级缓存中的一级缓存,这个一级缓存框架源码解析,第一篇Spring5.0源码解析(一)

基于注解形式创建bean

import com.douzi.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanConfig {
    @Bean
    public User getUser(){
     return  new User();
    }
}
public class User {
    private  String name;
    private  int age;

    public User() {
        System.out.println("初始化User");
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
import com.douzi.config.BeanConfig;
import com.douzi.domain.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AnocationSpring {
    private static AnnotationConfigApplicationContext applicationContext;
    public static void main(String[] args) {
        applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        User user = applicationContext.getBean("getUser", User.class);
        User user2 = applicationContext.getBean("getUser", User.class);
        System.out.println(user==user2);

    }
}

框架源码解析,第一篇Spring5.0源码解析(一)

按住CTRL+H,可以查看出spring实现注解的方法有256种下面一一列举出几种常见的,大家比较熟悉的注解

Override重载,Autowired springmvc中@ctroller或者实现类中注入接口,@Resource资源加载有点印象,
Lazy懒加载放在@bean上,Scope可以选择单例或者原型默认是单例,要变成原型需要@Scope("prototype"),@Service,
表明Service层会注入IOC,@ComponentScan扫包注入ioc,可以选择排除或者包含哪些@Async异步开始线程,
@Bean 注入bean的一种方式,可以引入外部组件常常和@Configuration类似XML配置文件一起用,
@Validated 放在controller对bean里面的参数进行校验,@Component最常见的注入Bean的方法,
@Import导入第三方jar包注入spring进行管理。@Repository Dao注入bean

@Service和@Component的区别?没什么特别的区别,@Service包含@Component并且自带业务含义属性,都是给IOC管理bean。

spring bean的作用域:

singleton单例模式,全局有且仅有一个实例。

prototype原型模式

每次获取Bean的时候都会有一个新的实例。

request表示针对每次请求都会产生一个新的Bean对象,并且该Bean对象仅在当前Http请求内有效。

session作用域表示每次请求都会产生一个新的Bean对象,并且该Bean仅在当前Http session内有效。

============================================================

@Condition

Condition 是在spring4.0 增加的条件注解,通过这个可以功能可以实现选择性的注入Bean操作,接下来先学习下Condition是如何使用的,然后分析spring源码了解其中的实现原理。

实现案例:

在Spring容器加载中,如果当前环境是WIN7操作系统就装配win7实体类、其他系统就不装配

public class MyCondition implements Condition {
    /**
     * 根据条件判断上下文context
     *
     * @param context
     * @param metadata
     * @return
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 1.获取当前环境配置
        Environment environment = context.getEnvironment();
        String osName = environment.getProperty("os.name");
        if (osName.equals("Windows 7")) {
            // 返回true 就是能够创建该bean
            return true;
        }
        return false;
    }
}
@Bean
@Conditional(MyCondition.class)
public Win7Entity win7Entity() {
    return new Win7Entity();
}

 就是执行@bean装配对象的时候先进行condition条件判断如果返回true就装配,如果不false就不装配。

@Import注解

@Import 是被用来整合所有在@Configuration注解中定义的bean配置

@Import({V5UserEntity.class, V6UserEntity.class})

默认注册beanid为 全路径地址

——————————————————————————————————————————————————————

ImportSelector

ImportSelector接口是至spring中导入外部配置的核心接口,在SpringBoot的自动化配置和@EnableAutoConfiguration(功能性注解)都有它的存在。

public class MyImportSelector implements ImportSelector {
    /**
     * AnnotationMetadata 注解信息
     *
     * @param importingClassMetadata
     * @return
     */
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 添加需要注册的spring容器的类
        return new String[]{"com.dz.v4.V7UserEntity"};
    }
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MyImportSelector.class)
public @interface EnableUser {
}

ImportBeanDefinitionRegistrar

ImportBeanDefinitionRegistrar手动注册bean

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 手动注册bean
        String beanName = "payEntity";
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(PayEntity.class);
        registry.registerBeanDefinition(beanName, rootBeanDefinition);
    }
}

 使用FactoryBean注册对象

public class MyFactoryBean implements FactoryBean<MemberEntity> {
    public MemberEntity getObject() throws Exception {
        return new MemberEntity();
    }

    public Class<?> getObjectType() {
        return MemberEntity.class;
    }

    public boolean isSingleton() {
        return false;
    }
}
@Bean
public MyFactoryBean myFactoryBean() {
    return new MyFactoryBean();
}

 区别:BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似

获取所有容器管理的bean,name

import douzi.config.BeanConfig;
import douzi.domain.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringStart {
    private static AnnotationConfigApplicationContext applicationContext;

    public static void main(String[] args) {
        applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
        User user1 = applicationContext.getBean("user", User.class);
        User user2 = applicationContext.getBean("user", User.class);
        System.out.println(user1==user2);
        String [] bename =applicationContext.getBeanDefinitionNames();
        for(int i=0;i<bename.length;i++){
            System.out.println(bename[i]);
        }
    }

}

框架源码解析,第一篇Spring5.0源码解析(一)

@Primary与@Qualifier区别这个是@Autowired 接口出现多个实现类的时候设置优先级和指定使用哪个实现类

每一行代码都有它的涵义,多问一句为什么;别怕,理清思路,一切代码都是数据的流动和转化,耐心一点,慢慢积累!一起加油!!!

 

 

 

相关标签: 源码解析