基于注解的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