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里面进行管理呢