ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar接口是也是spring的扩展点之一,
它可以支持我们自己写的代码封装成BeanDefinition对象;实现此接口的类会回调postProcessBeanDefinitionRegistry方法,注册到spring容器中。
把bean注入到spring容器不止有 @Service @Component等注解方式;还可以实现此接口。
接口的使用很简单,使用@Import注解导入这个类即可。
通过调用它的registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)方法,
AnnotationMetadata :当前类的注解信息
BeanDefinitionRegistry :BeanDefinition注册类
ApplicationContextAware接口以及XXXAware接口
通俗的解释:如果在某个类里面想要使用spring的一些东西,就可以通过实行XXXAware接口告诉spring,spring会到最后给你送过来,而接收的方式是通过实现接口唯一的方法set-XXX。
比如,有一个类想要使用当前的ApplicationContext,那么我们只需要让它实现ApplicationContextAware接口,然后实现接口中唯一的方法void setApplicationContext(ApplicationContext applicationContext)就可以了,spring会自动调用这个方法将applicationContext传给我们,我们只需要接收就可以了。
BeanFactoryPostProcesser
BeanFactoryPostProcesser和BeanPostProcesser名字很类似 这个是BeanFactory的后置处理器
执行时机:这个接口的作用是在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
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.toString()); } }
2. 然后定义一个事件实现类,和观察者模式一样 拥有事件原对象
public class MyApplicationEvent extends ApplicationEvent { private Object source; private Date eventDate; public MyApplicationEvent(Object source,Date eventDate) { super(eventDate); this.source=source; System.out.println("我发布的事件"); } @Override public String toString() { return "MyApplicationEvent{" + "source=" + source + ", eventDate=" + eventDate + '}'; } }
3.最后把事件发布出去即可 相当于观察者模式中的c.wakeUp();(小孩哭这个动作)
@Test public void test01(){ AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class); applicationContext.publishEvent(new MyApplicationEvent(applicationContext,new Date()) { }); 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); } }
Spring Bean的生命周期
Bean的生命周期就是Bean创建—销毁—初始化的过程,这些都由容器管理
我们可以自定义销毁和初始化的方法,特别在配置数据源的时候很有用
@Bean(initMethod="init",destroyMethod="detory") public Car car(){ return new Car(); }
初始化时机:对象创建完成并赋值好,调用初始化方法。。。
销毁:容器关闭的时候进行销毁(多实例需要自己手动调用)
通过让Bean 实现InitializingBean(定义初始化逻辑)DisposableBean(定义销毁逻辑)
我们从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
BeanFactory和FactoryBean的区别
顾名思义:BeanFactory是Bean工厂,是一个工厂 参考工厂的设计模式,FactoryBean是一个Bean 是一个java类
FactoryBean接口对于Spring框架占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来的便利。
该接口中定义了三个方法
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
Spring如何解决循环依赖
Spring在Sigleton Bean是默认支持循环依赖的,prorotype不支持
Spring循环依赖其实就是说的对象属性的注入
Spring的对象如何创建,属性如何注入