Spring源码(基于注解)

858 阅读3分钟

基于注解的Spring源码分析

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class); //包含了配置类和包扫描

一、 组件添加

@ComponentScan: 指定要扫描的包

@Bean: 给容器中注册一个Bean;类型为返回值的类型,id默认是用方法名作为id

@Scope:调整作用域
prototype:多实例的:ioc容器启动并不会去调用方法创建对象放在容器中。
          每次获取的时候才会调用方法创建对象;
singleton:单实例的(默认值):ioc容器启动会调用方法创建对象放到ioc容器中。
           以后每次获取就是直接从容器(map.get())中拿,
request:同一次请求创建一个实例
session:同一个session创建一个实例
@Lazy 懒加载:
    单实例bean:默认在容器启动的时候创建对象;
    懒加载:容器启动不创建对象。第一次使用(获取)Bean创建对象,并初始化;
bean的生命周期(bean创建---初始化----销毁的过程)
1)、指定初始化和销毁方法;通过@Bean指定init-method和destroy-method;
2)、通过让Bean实现InitializingBean(定义初始化逻辑),DisposableBean(定义销毁逻辑);
3)、可以使用JSR250;
		@PostConstruct:在bean创建完成并且属性赋值完成;来执行初始化方法
		@PreDestroy:在容器销毁bean之前通知我们进行清理工作
4)、BeanPostProcessor【interface】:bean的后置处理器;在bean初始化前后进行一些处理工作;
		postProcessBeforeInitialization:在初始化之前工作
		postProcessAfterInitialization:在初始化之后工作
		
    BeanPostProcessor原理
    populateBean(beanName, mbd, instanceWrapper);给bean进行属性赋值
    initializeBean 实例化bean
    {
        applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //遍历得到容器中所有的BeanPostProcessor;挨个执行beforeInitialization,一但返回null,跳出for循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization
        invokeInitMethods(beanName, wrappedBean, mbd);执行自定义初始化
        applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    Spring底层对 BeanPostProcessor 的使用;
		bean赋值,注入其他组件,@Autowired,生命周期注解功能,@Async等功能都是有xxx BeanPostProcessor实现的;

@Configuration:配置类==配置文件,告诉Spring这是一个配置类

@Component,@Service,@Controller,@Repository: 组件扫描中useDefaultFilters = true默认开启的,会扫描自己定义的类

@Conditional:类中组件统一设置。满足当前条件,这个类中配置的所有bean注册才能生效;

@Conditional({WindowsCondition.class}) //widow系统@Configuration中的bean才生效

@Primary

@Import:导入组件,id默认是组件的全类名,或实现ImportSelector或ImportBeanDefinitionRegistrar的全类名

@Import({Color.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})

工厂模式:实现FactoryBean 例如,FactoryBean

// 工厂Bean获取的是调用getObject创建的对象
Object bean2 = applicationContext.getBean("colorFactoryBean");
//要获取工厂Bean本身,我们需要给id前面加一个&:&colorFactoryBean
Object bean4 = applicationContext.getBean("&colorFactoryBean");

总结:

给容器中注册组件;
1)、包扫描+组件标注注解(@Controller/@Service/@Repository/@Component)[自己写的类]
2)、@Bean[导入的第三方包里面的组件]
3)、@Import[快速给容器中导入一个组件]
      1)、@Import(要导入到容器中的组件);容器中就会自动注册这个组件,id默认是全类名
      2)、ImportSelector:返回需要导入的组件的全类名数组;
      3)、ImportBeanDefinitionRegistrar:手动注册bean到容器中
4)、使用Spring提供的 FactoryBean(工厂Bean);
      1)、默认获取到的是工厂bean调用getObject创建的对象
      2)、要获取工厂Bean本身,我们需要给id前面加一个&
         &colorFactoryBean

二、 组件赋值

@Value

@Autowired

@PropertySource

@PropertySources

@Profile

三、 组件注入

方法参数

构造器注入

ApplicationContextAware

xxxAware

四、 AOP

@EnableAspectJAutoProxy

@Before/@After/@AfterReturning/@AfterThrowing/@Around

@Pointcut

五、 声明式事务

@EnableTransactionManagement

@Transactional