手撸Spring09: 通过继承感知类 获取Spring容器提供的一些资源

Srping是有提供一些资源供我们外部获取的, 比如Spring上下文,bean工厂等等, 我们要去获取资源进行扩展时, 并不需要进行注入,而是通过一些感知类来获取资源即可.

首先是定义 标记接口

Aware

说起来你可能不信,但是他的源码就是这么简单

 package com.linnine.spring.beans.factory;

/**
 * 定义一个感知接口
 * 用来归纳
 */
public interface Aware {
}

然后是定义一些感知类

容器感知类

用于感知bean工厂

package com.linnine.spring.beans.factory;

import com.linnine.spring.beans.BeansException;

public interface BeanFactoryAware extends Aware{

    void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

用于感知ClassLodaer

package com.linnine.spring.beans.factory;

public interface BeanClassLoaderAware extends Aware{

    void setBeanClassLoader(ClassLoader classLoader);
}

用于感知beanName

package com.linnine.spring.beans.factory;

public interface BeanNameAware extends Aware{

    void setBeanName(String name);
}

用于感知上下文

package com.linnine.spring.context;

import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.Aware;

public interface ApplicationContextAware extends Aware {

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

包装一个感知处理器,这里就有点像是在使用了

package com.linnine.spring.context.support;

import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.context.ApplicationContext;
import com.linnine.spring.context.ApplicationContextAware;

public class ApplicationContextAwareProcessor implements BeanPostProcessor {

    private final ApplicationContext applicationContext;

    public ApplicationContextAwareProcessor(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof ApplicationContextAware){
            ((ApplicationContextAware) bean).setApplicationContext(applicationContext);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

因为ApplicationContext并不能直接在创建Bean时获取,所以外部虽然实现了这个感知类,但想要获取, 可以先通过前置处理器先帮忙注入.

然后当某个Bean是实现ApplicationContextAware感知类时,就帮他操作一下.

然后把这个后处理器添加进去

package com.linnine.spring.context.support;


import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.ConfigurableListableBeanFactory;
import com.linnine.spring.beans.factory.config.BeanFactoryPostProcessor;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.context.ConfigurableApplicationContext;
import com.linnine.spring.core.io.DefaultResourceLoader;

import java.util.Map;

/**
 * 应用上下文 抽象类实现
 */
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {

    @Override
    public void refresh() throws BeansException {
        //创建beanFactory, 并加载BeanDefinition
        refreshBeanFactory();
        //获取BeanFactory
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        //09 添加ApplicationContextAwareProcessor 让继承自ApplicationContextAware的bean对象都能获取到ApplicationContext
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        //在Bean实例化前 调用后处理器
        invokeBeanFactoryPostProcessors(beanFactory);
        //注册bean处理器
        registerBeanPostProcessors(beanFactory);
        //提前实例化单例对象
        beanFactory.preInstantiateSingletons();
    }
    
	//其他...
}

然后就是其他的一些感知类,我们要帮他在创建bean的过程中,感知到这些需要的东西.

package com.linnine.spring.beans.factory.support;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.PropertyValue;
import com.linnine.spring.beans.PropertyValues;
import com.linnine.spring.beans.factory.*;
import com.linnine.spring.beans.factory.config.AutowireCapableBeanFactory;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.beans.factory.config.BeanReference;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

@Getter
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {

    private InstantiationStrategy instantiationStrategy =new CglibSubclassingInstantiationStrategy();

    @Override
    protected Object createBean(String beanName, BeanDefinition beanDefinition,Object[] args) throws BeansException {
        Object bean;
        bean = createBeanInstance(beanDefinition,args);
        //补充属性
        applyPropertyValues(bean,beanDefinition);
        //执行bean的初始化方法和BeanPostProcessor的前置方法和后置方法
        bean = initializeBean(beanName,bean,beanDefinition);

        //注册 有实现 DisposableBean 接口的bean对象
        registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);

        addSingletonBean(beanName,bean);
        return bean;
    }
       private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition){
        //09新增 如果是感知类
        if (bean instanceof Aware){
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(this);
            }
            if (bean instanceof BeanClassLoaderAware){
                ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
            }
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
        }

        //执行前置处理器
        Object wrappedBean=applyBeanPostProcessorsBeforeInitialization(bean,beanName);
        //待完成 执行初始化方法
        try {
            invokeInitMethods(beanName, wrappedBean, beanDefinition);
        } catch (Exception e) {
            throw new BeansException("Invocation of init method of bean[" + beanName + "] failed", e);
        }
        //执行后处理器
        wrappedBean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

        return wrappedBean;
    }
	//其他...
}

测试准备,这次主要改装service来获取一些spring提供的资源, 以后需要这些资源基本也这么搞了.

@Data
public class UserService implements InitializingBean, DisposableBean , BeanNameAware, BeanClassLoaderAware, ApplicationContextAware, BeanFactoryAware {

    private ApplicationContext applicationContext;
    private BeanFactory beanFactory;

    private String uId;

    private String company;

    private String location;

    private UserDao userDao;

    public String queryUserInfo(){
        return userDao.queryUserName(uId)+uId+company+location;
    }


    @Override
    public void afterPropertiesSet() {
        System.out.println("执行:UserService.afterPropertiesSet");
    }

    @Override
    public void destroy() {
        System.out.println("执行:UserService.destroy");
    }


    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("ClassLoader:" + classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;

    }

    @Override
    public void setBeanName(String name) {
        System.out.println("Bean Name is:" + name);

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;

    }
}

开始测试

@Test
public void test_XML(){
    //初始化
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
    applicationContext.registerShutdownHook();

    UserService userService = (UserService) applicationContext.getBean("userService", UserService.class);

    String s = userService.queryUserInfo();
    System.out.println("测试结果:"+s);
    System.out.println("ApplicationContextAware:"+userService.getApplicationContext());
    System.out.println("BeanFactoryAware:"+userService.getBeanFactory());
}

报错一:

java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given

debug了一下是在创建这个后处理器时没有空构造,因为上面写的不能空构造
在这里插入图片描述
然后来去调用ApplicationContextAwareProcessor的地方看看.
在这里插入图片描述
往里面扎了一下,是因为后处理器也会注册到BeanDefinition中,然后再创建Bean的时候报错了?

我人麻了,好像打开的小窗口重叠了,把我刚才解决问题的步骤没保存下来!!!

再重新码一下,就是这些Bean后处理器我之前为了填坑, 是把他丢到了Bean管理了,但其实是有专门一个类用来管理这些后处理器的存取的, 而不是跟着重新创建一遍.

还好我有一批一批的提交代码到git!

AbstractBeanFactory

主要的是这个,bean后处理器在这里面管理

package com.linnine.spring.beans.factory.support;


import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
import com.linnine.spring.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.util.Assert;

import java.util.ArrayList;
import java.util.List;
//09 从实现BeanFactory改成实现ConfigurableBeanFactory
public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory {
    //09新增 管理后处理器 源码的获取不是通过new这个, 这里临时用一下
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<>();

    public Object getBean(String beanName,Object... args){
        //继承自DefaultSingletonBeanRegistry 的方法
        Object bean = getSingleton(beanName);
        if (bean != null){
            return bean;
        }
        //获取不到就两个抽象方法 让实现此类的去做实现
        BeanDefinition beanDefinition = getBeanDefinition(beanName);
        return createBean(beanName,beanDefinition,args);

    }

    protected abstract BeanDefinition getBeanDefinition(String name) throws BeansException;

    //添加参数
    protected abstract Object createBean(String beanName,BeanDefinition bean,Object... args) throws BeansException;

    //09 改造
    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
    }
    //09 转移 原本的获取改成从这里获取
    public BeanPostProcessor[] getBeanPostProcessors(){
        return this.beanPostProcessors.toArray(new BeanPostProcessor[0]);
    }
}

然后其他的就是微调了

DefaultListableBeanFactory

在这里插入图片描述
ConfigurableBeanFactory

package com.linnine.spring.beans.factory.config;


import com.linnine.spring.beans.factory.BeanFactory;

//09 改成接口 实现BeanFactory
public interface ConfigurableBeanFactory extends BeanFactory {

    //09 添加一个接口方法
    void addBeanPostProcessor(BeanPostProcessor var1);

}

ConfigurableListableBeanFactory

package com.linnine.spring.beans.factory;


import com.linnine.spring.beans.factory.config.AutowireCapableBeanFactory;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.ConfigurableBeanFactory;

//09 多实现了后面两个
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory,ConfigurableBeanFactory {

    void preInstantiateSingletons();

    //09去除添加后处理器的方法

    BeanDefinition getBeanDefinition(String name);

    void destroySingletons();
}

这样就能跑通了

在这里插入图片描述

最后有点不理解的是,为什么后处理器要放在一个叫Bean工厂的抽象类AbstractBeanFactory里面进行管理呢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值