Spring的核心接口
Spring Bean的生命周期
Bean的生命周期就是Bean创建—销毁—初始化的过程,这些都由容器管理
我们可以自定义销毁和初始化的方法,特别在配置数据源的时候很有用
@Bean(initMethod="init",destroyMethod="detory") public Car car(){ return new Car(); }
AnnotatedBeanDefinitionReader 在spring上下文初始化的时候调用,
AnnotatedBeanDefinitionReader#register 可以往bean工厂注册beanDefinition,AnnotatedBeanDefinitionReader自己在初始化的时候会往bean工厂注册spring自带的beanFactoryPostProcessor和beanPostProcessor,
这些注册到bean工厂的list中,后面会使用到。
ClassPathBeanDefinitionScanner在spring启动的时候完成初始化的:
ClassPathBeanDefinitionScanner作用就是将指定包下的类通过一定规则过滤后 将Class 信息包装成 BeanDefinition 的形式注册到IOC容器中。
扫描类路径下的候选Component,构造BeanDefinition对象(实际为ScannedGenericBeanDefinition)
利用BeanDefinitionRegister注册BeanDefinition到bean工厂中,BeanDefinitionRegister是spring默认bean工厂DefaultListableBeanFactory的一个接口,用于注册BeanDefinition;
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh(); } ————————————————————————————————————this() public AnnotationConfigApplicationContext() { //在IOC容器中初始化一个 注解bean读取器AnnotatedBeanDefinitionReader this.reader = new AnnotatedBeanDefinitionReader(this); //在IOC容器中初始化一个 按类路径扫描注解bean的 扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this); }
我们从Spring核心接口的角度谈一下Spring Bean创建的过程,也就是Spring的生命周期
【ImportBeanDefinitionRegistrar接口】调用registerBeanDefinitions
【BeanFactoryPostProcessor接口】调用postProcessBeanFactory
... constructor...
【BeanNameAware接口】调用setBeanName方法
【BeanFactoryAware接口】调用setBeanFactory方法
【BeanPostProcessor接口】调用postProcessBeforeInitialization方法对属性进行更改
【InitializingBean接口】调用afterPropertiesSet方法
【init-method】调用<bean>的init-method属性指定的初始化方法
【BeanPostProcessor接口】调用postProcessAfterInitialization
【DiposibleBean接口】调用destroy方法
【destroy-method】调用<bean>的destroy-method属性指定的初始化方法
参考文章CSDN:https://www.cnblogs.com/javazhiyin/p/10905294.html
参考文章知乎:https://www.zhihu.com/question/38597960/answer/247019950?utm_source=wechat_session
ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar接口是spring的扩展点之一,
它可以支持我们自己写的代码封装成BeanDefinition对象;实现此接口的类会回调postProcessBeanDefinitionRegistry方法,注册到spring容器中。
把bean注入到spring容器不止有 @Service @Component等注解方式;还可以实现此接口。
接口的使用很简单,使用@Import注解导入这个类即可。
通过调用它的registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)方法,
AnnotationMetadata :当前类的注解信息
BeanDefinitionRegistry :BeanDefinition注册类
BeanFactoryPostProcesser
BeanFactoryPostProcesser和BeanPostProcesser名字很类似 这个是BeanFactory的后置处理器也是Spring的扩展点
执行时机:这个接口的作用是在Spring上下文的注册Bean定义的逻辑都跑完后,但是所有的Bean都还没真正实例化之前调用。
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
这个方法的主要用途就是通过注入进来的BeanFactory,在真正初始化Bean之前,再对spring上下文做一些动态修改。增加或者修改某些Bean定义的值,甚至再动态创建一些BeanDefinition都可以。
BeanDefinitionRegistryPostProcessor 是BeanFactoryPostProcesser的子类和父类相比 它额外定义了一个新的方法postProcessBeanDefinitionRegistry()
执行时机:这个子接口的方法postProcessBeanDefinitionRegistry会被Spring先于postProcessBeanFactory这个方法执行。
不过呢,其实这2个方法都是注入的spring的上下文,只不过声明类型不同罢了。所以可以做的事一模一样。
参考文章简书:https://www.jianshu.com/p/899bd8089352
ApplicationContextAware接口以及XXXAware接口
通俗的解释:如果在某个类里面想要使用spring的一些东西,就可以通过实行XXXAware接口告诉spring,spring会到最后给你送过来,而接收的方式是通过实现接口唯一的方法set-XXX。
比如,有一个类想要使用当前的ApplicationContext,那么我们只需要让它实现ApplicationContextAware接口,然后实现接口中唯一的方法void setApplicationContext(ApplicationContext applicationContext)就可以了,spring会自动调用这个方法将applicationContext传给我们,我们只需要接收就可以了。
BeanPostProcesser
BeanPostProcesser的作用是在Bean初始化前后处理一些工作
BeanPostProcesser名字虽然叫后置处理器,但是提供了两个方法postProcessBeforeInitialization和postProcessAfterInitialization,在Bean初始化之前和初始化之后分别调用,
我们的Bean可以实现此接口,然后重写上面两个方法
BeanPostProcesser调用原理:
像这种方法前后加一些东西的,一开始想到的是AOP,源码上看起来并不是AOP,而是在执行InitMethod(初始化方法)的前后分别调用两个方法
Spring对BeanPostProcesser的一些使用
BeanValidationPostProcessor 在Web里面对数据校验用的比较多
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (!this.afterInitialization) { doValidate(bean); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (this.afterInitialization) { doValidate(bean); } return bean; }
AutowiredAnnotationBeanPostProcessor 在对象创建完之后处理Autowired注解
ApplicationListener
ApplicationListener监听容器中发布的事件,事件驱动模型的开发
理解ApplicationListener 首先了解下观察者模式
现在我们自己发布一个事件的流程
1.首先写一个Listener实现ApplicationListener接口,接口中可以拿到事件源对象。相当于观察者模式的Observe实现类
@Component public class MyApplicationListener implements ApplicationListener<MyApplicationEvent> { @Override public void onApplicationEvent(MyApplicationEvent event) { System.out.println("我接收到事件======"+event.getInfo()); }
2. 然后定义一个事件实现类,和观察者模式一样 拥有事件原对象
public class MyApplicationEvent extends ApplicationEvent { private String info; public MyApplicationEvent(Object source,String info) { super(source); this.info=info; System.out.println("事件构造"); } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } }
3. 单元测试最后把事件发布出去即可 相当于观察者模式中的c.wakeUp();(小孩哭这个动作)
@Test public void test01(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); System.out.println("发布事件"); applicationContext.publishEvent(new MyApplicationEvent(applicationContext,"开始吃饼干") { }); applicationContext.close(); }
打印结果:
发布事件
事件构造
我接收到事件======开始吃饼干
Spring的监听器的实现原理和Observe设计模式应该一样,即循环所有的观察者,对分别调用响应事件的方法。这里的publishEvent就相当于观察者模式中的小孩哭
public void publishEvent() { cry = true; wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed", this); for(Observer o : observers) { o.actionOnWakeUp(event); } }
BeanFactory和FactoryBean的区别
顾名思义:BeanFactory是Bean工厂,是一个工厂 参考工厂的设计模式,FactoryBean是一个Bean 是一个java类
FactoryBean接口对于Spring框架占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来的便利。
该接口中定义了三个方法
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();