Spring原理(通过源码深入分析Spring生命周期和依赖注入、动态代理的实现)

一、分析BeanPostProcessor接口:

这个接口里面的两个方法每个Spring容器里面的Bean初始化时候都会调用,
一个是postProcessBeforeInitialization,
一个是postProcessAfterInitialization,
都是在bean属性设置完成后,进行调用。
postProcessBeforeInitialization在init方法之前调用,
postProcessAfterInitialization在之后调用。
这个接口是为什么ApplicationContextAware能够实现依赖注入的关键点。
我们可以利用这两个方法调用的时间,做一些bean初始化过程中的自定义的操作。

二、仿照Spring的ApplicationContextAware接口写一个自定义的依赖注入方法

(1)、声明SpringContextAwar接口

public interface SpringContextAwar {
    public void setApplicationContext(ApplicationContext applicationContext);
}

(2)、创建EchoBeanProcessor,实现BeanPostProcessor接口

@Component
public class EchoBeanProcessor implements BeanPostProcessor {

    @Autowired  //spring容器上下文
    private ApplicationContext applicationContext;

    @Override  
    //bean init方法之前,属性设置之后执行
    public Object postProcessBeforeInitialization(Object bean, String s) throws BeansException {

    //instanceof可以判断接口继承,
    //所以当spring容器初始化bean的时候,
    //发现此bean实现了SpringContextAwar接口
    //就将bean转为SpringContextAwar对象,
    //通过SpringContextAwar的setApplicationContext方法将容器中的applicationContext当参数,
    传入当前bean的setApplicationContext方法,
    //从而完成依赖注入
    if (bean instanceof SpringContextAwar){
        SpringContextAwar awar=(SpringContextAwar)bean;
        awar.setApplicationContext(applicationContext);
    }
	//实现动态代理
    if (bean instanceof User){
        System.out.println("*************postProcessBeforeInitialization************"+bean.getClass());
       //动态代理,如果初始化的是User,就返回logUser对象,那么从spring容器中
       //context.getBean(User.class)就是拿出的logUser对象。
    }
        return new logUser(); 
    return bean;
}

@Override  //bean init方法之后
public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
    if (bean instanceof User){
        System.out.println("*************postProcessAfterInitialization************"+bean.getClass());
    }
    	return bean;
    }
}

(3)、声明一个Dog类实现SpringContextAwar.接口

Dog.class

@Component
public class Dog implements SpringContextAwar {

    private User user;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.user=applicationContext.getBean(User.class);
    }

    public void show(){
        System.out.println("Dog show:"+user.getAge());
    }
}

理解:

Spring的动态代理(AOP),依赖注入等等实现,基本上就是这个原理,
通过BeanPostProcessor接口的两个方法,在bean初始化的时候,
做一些处理(动态代理或者依赖注入).
依赖注入的实现:bean属性设置之后,发现本bean实现了SpringContextAwar方法,
于是在postProcessBeforeInitialization方法中将本dean转换为SpringContextAwar.
再通过SpringContextAwar调用setApplicationContext方法,
将Spring容器中的ApplicationContext对象注入到bean对应的属性中去,
然后要装配的bean(Dog)里面就可以通过ApplicationContext对象拿到任何Spring容器中的属性,
从而完成依赖注入。

你可能感兴趣的:(Spring)