Spring的核心接口

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的对象如何创建,属性如何注入

原文地址:https://www.cnblogs.com/ssskkk/p/12942375.html