这一篇内容量比较多也不好理解,最好的理解方式是手敲理解,去思考为什么这么设计,好处是什么,学习到了可不可以应用到自己实践项目当中,相信你可以受益匪浅。
咱们要实现两大功能1是实现应用上下文,这个的意思就是说我们在实例化时将配置文件交给上下文类,上下文类会通过内部处理后会解析XML然后将Bean注册并创建出Bean的过程,我们对于使用的话什么都不操作,看看如下的使用入口,是不是更简便了
再看看之前的写法,还需要自己实例化,还得找对应的Bean的解析类等等,咱们优化过后,将所有的数据刷新到容器里就都在上下文操作类做了
第二个就是可以在Bean解析完后放入Bean定义中时在Bean创建之前修改Bean的信息,然后在实例化后对实例Bean进行修改的操作扩展
BeanFactoryPostProcssor:Bean的前置处理,Bean对象注册后实例化之前对Bean定义信息进行修改操作。
BeanPostProcessor:Bean的后置处理,bean对象实例化之后可以进行Bean的修改,甚至可以更改Bean的对象。
这一期会稍微复杂一点,涉及的改动也会多一点,本期更改完后,后面的扩展都是很方便了,也很简单。
本篇代码github地址:https://github.com/dufGIT/spring-sourcecode.git
1.UML类图
1.1 应用上下文类
1. ApplicationContext:定义上下文接口,表明是上下文接口,继承ListableBeanFactory,ListableBeanFactory是BeanFactory里的,继承此接口Context上下文就有了根据BeanFactoryPostProcssor类以及BeanPostProcssor类来获取对应自定义类,方法为:getBeansOfType(Class<T> type),还有了从BeanDefinition里获取beanName名称集合的功能,方法为:getBeanDefinitionNames(),现在看肯定绕甚至不懂,自己动手敲看代码逻辑,其实就明白我这个段说的意思了。
2. ConfigurableApplicationContext:接口,继承ApplicationContext,定义了刷新方法refresh(),代表要将xml里的bean通过解析刷新到程序容器里的一系列操作。
3. AbstractApplicationContext:抽象类,此类实现ConfigurableApplicationContext类,实现刷新方法refresh(),并继承了DefaultResourceLoader,可获得不同的资源处理器就有了可以处理xml解析数据的入口,此类里还定义了将Bean对象刷新到容器里的方法功能refreshBeanFactory()供子类去实现具体功能,以及定义了获取新添加的ConfigurableListableBeanFactory接口的方法为:getBeanFactory()供子类使用
4. AbstractRefreshableApplicationContext:抽象类,继承AbstractApplicationContext,实现getBeanFactory()以及refreshBeanFactory()方法,定义了loadBeanDefinitions(DefaultListableBeanFactory beanFactory)方法;
5. AbstractXmlApplicationContext:抽象类,继承AbstractRefreshableApplicationContext类,实现loadBeanDefinitions()方法,此方法实现了从xml中解析Bean以后放入到BeanDefinition里。定义了getConfigLocations()方法,用来获取配置文件路径的方法
6.ClassPathXmlApplicationContext:普通类,继承AbstractXmlApplicationContext类,实现getConfigLocations()将获取配置文件路径,此类也是入口,通过构造方法将String路径传入以后调用refresh()刷新方法。
这样一来应用上下文相关的类就都说完了
咱们在回到今天说的主题上上下文说完了,就该说一下Bean的前置和后置修改的情况,前置是在Bean放入了BeanDefinition中时的修改,后置是在创建Bean对象的修改,所以我们大致就知道他们功能的所在位置,一个是refresh()时,将xml里数据解析到BeanDefinition后就可以了,另一个是createBean()方法里已经创建好对象后进行修改操作,那么咱们接下来说一下bean前置后置相关类
1.2 Bean前置后置
1.2.1 BeanFactoryPostProcessor:Bean前置接口,定义了postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)前置方法,所有的为被实例化在Bean容器被定义时即可修改
1.2.2 BeanPostProcessor:Bean后置接口,定义了postProcessBeforeInitialization(),
postProcessAfterInitialization()方法。是在Bean对象创建完毕即可修改
到这一节之前的改动的有点多,原作者为了贴合Spring源码,添加了很多以BeanFactory为结尾的类,还有就是在创建bean后处理自定义修改Bean对象,所以以前的类也需要改动,或方法或继承
1.3 BeanFactory为后缀类的改动
1.3.1 HierarchicalBeanFactory:添加一个BeanFactory接口,暂时没有实际使用,也没有定义方法
1.3.2 ConfigurableBeanFactory:添加一个BeanFactory接口,定义addBeanPostProcessor(BeanPostProcessor beanPostProcessor)方法,代表往容器中添加后置接口,留着子类实现。
1.3.3 ListableBeanFactory:添加一个BeanFactory接口,定义方法getBeansOfType(Class<T> type)方法,这里的作用根据前置后置接口来寻找实现后置与前置的自定义来,目的是这样就可以调用实现方法。getBeanDefinitionNames()暂时需求里没有调用此方法,但是实现了,不算核心。
1.3.3 AutowireCapableBeanFactory:添加一个BeanFactory接口,定义方法applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName),实例化之后的对对象修改。定义修改后返回对象方法applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName);等着子类实现。
1.3.4 ConfigurableListableBeanFactory:添加一个BeanFactory接口,继承了ConfigurableBeanFactory、ListableBeanFactory、AutowireCapableBeanFactory,并定义了getBeanDefinition(String beanName)、preInstantiateSingletons()(此方法是刷新上下文里会调用此方法,在全部处理完后,如果有没有被实例化的进行实例化操作)、addBeanPostProcessor(BeanPostProcessor beanPostProcessor)定义添加后置接口方法
1.3.5 DefaultListableBeanFactory:这个接口修改为实现ConfigurableListableBeanFactory接口,实现preInstantiateSingletons()以及getBeansOfType(Class<T> type)方法。
1.3.6 AbstractAutowireCapableBeanFactory:DefaultListableBeanFactory的继承类,修改为实现AutowireCapableBeanFactory接口,AbstractAutowireCapableBeanFactory类在CreateBean方法里添加initialization(),此方法里又实现了AutowireCapableBeanFactory接口applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()。
以上就是这一期的所有的改动。
2.代码实现
2.1 上下文接口实现
context包下,是此次新增的目录
ApplicationContext:定义上下文接口
public interface ApplicationContext extends ListableBeanFactory{
}
ConfigurableApplicationContext: 继承ApplicationContext,定义刷新方法,是核心方法,需要在其子类实现刷新方法进行将文件里的数据刷新到容器的操作。
public interface ConfigurableApplicationContext extends ApplicationContext {
/**
* 刷新容器
*
* @throws BeansException
*/
void refresh() throws BeansException;
}
AbstractApplicationContext:此抽象类继承了DefaultResourceLoader(就有了处理xml中数据的能力),实现接口ConfigurableApplicationContext,就需要具体实现刷新接口,
第一点定义抽象方法refreshBeanFactory()供其他子类实现具体刷新到Bean容器功能,
第二点定义获取BeanFactory方法getBeanFactory(),供其子类实现,
第三点就是通过如果在bean实例化之前有要修改Bean的操作则将自定义操作类调用方法使用,
第四点是如果有BeanPostProcessor则添加到容器里,供后续实例化使用。
第五点是将beanDefinition容器里的数据循环进行获取bean操作,看是否有没被实例化的Bean,有则进行实例化操作
context.supprot包下
// 定义一些基本的上下文
// 定义一些方法,由一层一层子类实现
// 也在本类自实现了如invokeBeanFactoryPostProcessors(),registerBeanPostProcessors()
// 也实现了父类的继承的各个方法
// 实现了ConfigurableApplicationContext接口,实现refresh()
// 第7节加
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
// 使用模板方法
@Override
public void refresh() {
// 1.创建beanFactory
// 2.将创建完的beanFactory和配置文件路径传输到资源处理器里
// 3.从资源处理器获取输入流,根据流解析bean以及属性数据并注册到bean容器里
refreshBeanFactory();
// 2.获取beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 3.在bean实例化之前,执行BeanFactoryPostProcessor(Invoke factory processors registered as beans in the context)
// 3.1 根据BeanFactoryPostProcessor来判断是否是自定义实现子类,是就创建bean,并注册到单例类(创建自定义类Bean(MyBeanFactoryPostProcessor))
// 3.2 根据得到的BeanFactoryPostProcessor接口来调用postProcessBeanFactory方法(此时beanDefinition里的属性已经修改)
invokeBeanFactoryPostProcessors(beanFactory);
// 4.BeanPostProcessor需要提前于其他Bean对象实例化之前执行注册操作
// 4.1 通过getBeansOfType()找到与BeanPostProcessor相关的类,
// 4.2 找到以后调用将当前的BeanPostProcessor放入集合里(做标识-后续其他bean实例创建可进行后置处理更改对象bean)
registerBeanPostProcessors(beanFactory);
// 5.提前实例化单例bean对象
// 通过beanDefinationMap里的实例对象将后续bean实例进行实例化,并处理后置修改的对象
beanFactory.preInstantiateSingletons();
}
protected abstract void refreshBeanFactory();
protected abstract ConfigurableListableBeanFactory getBeanFactory();
// 在bean实例化之前,执行BeanFactoryPostProcessor,自定义实现进行bean的修改
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 获取和BeanFactoryPostProcessor类有关系的的类-这里主要是获取BeanFactoryPostProcessor的子实现接口
Map<String, BeanFactoryPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanPostProcessorMap.values()) {
// 调用用户自定义实现的子接口
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
}
}
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 根据BeanPostProcessor获取其子实现接口
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
// 将beanPostProcessor添加到集合里
beanFactory.addBeanPostProcessor(beanPostProcessor);
}
}
@Override
public <T> Map<String, T> getBeansOfType(Class<T> type) {
return getBeanFactory().getBeansOfType(type);
}
@Override
public String[] getBeanDefinitionNames() {
return getBeanFactory().getBeanDefinitionNames();
}
@Override
public Object getBean(String name) throws BeansException {
return getBeanFactory().getBean(name);
}
@Override
public Object getBean(String name, Object... args) {
return getBeanFactory().getBean(name, args);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return getBeanFactory().getBean(name, requiredType);
}
}
AbstractRefreshableApplicationContext:继承AbstractApplicationContext,实现refreshBeanFactory()方法,并定义抽象加载beanDefinition方法loadBeanDefinitions()供其子类实现,实现了父类的方法为getBeanFactory()
// AbstractRefreshableApplicationContext此类主要是1.创建beanFactory,2.定义loadBeanDefinitions,3.定义获取beanFactory
// 此类继承了AbstractApplicationContext,定义了一些方法由当前类实现如:1.refreshBeanFactory(),2 getBeanFactory()
// 刷新应用上下文
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
private DefaultListableBeanFactory beanFactory;
@Override
protected void refreshBeanFactory() {
// 创建DefaultListableBeanFactory,也就是创建beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 获取资源并得到数据
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
// 创建DefaultListableBeanFactory()类
private DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory();
}
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory);
// 将当前创建的bean直接返回就可
@Override
protected ConfigurableListableBeanFactory getBeanFactory() {
return beanFactory;
}
}
AbstractXmlApplicationContext:继承AbstractRefreshableApplicationContext类,实现loadBeanDefinitions()方法,解析xml中的bean并放入容器里一系列操作,定义了getConfigLocations()抽象方法,供其子类实现
// AbstractXmlApplicationContext抽象类主要是调用解析xml中的bean并加载到系统里,
// 继承AbstractRefreshableApplicationContext类用来创建beanFactory然后定义loadBeanDefinitions让当前子类实现
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableApplicationContext {
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
// 开始调用上一章节的应用上下文资源解析核心类
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory, this);
// 改为获取传过来参数配置文件的路径
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 获取资源并解析资源里的数据
beanDefinitionReader.loadBeanDefinitions(configLocations);
}
}
protected abstract String[] getConfigLocations();
}
ClassPathXmlApplicationContext:继承AbstractXmlApplicationContext类,根据外部使用new ClassPathXmlApplicationContext(String path)将配置文件路径传入到此类全局变量里,并调用刷新方法,来完成bean的加载解析注册到容器的操作。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
// 获取配置文件的路径集合:如classpath:useContext.xml
private String[] configLoctions;
public ClassPathXmlApplicationContext() {
}
/*
* @Author df
* @Description 从xml中加载BeanDefinition并刷新上下文。
* @Date 10:26 2021/11/30
* @Param [configLocations]
* @return
**/
public ClassPathXmlApplicationContext(String configLocations) {
this(new String[]{configLocations});
}
/*
* @Author df
* @Description 从xml中加载BeanDefinition并刷新上下文。
* @Date 10:26 2021/11/30
* @Param [configLocations]
* @return
**/
public ClassPathXmlApplicationContext(String[] configLocations) {
this.configLoctions = configLocations;
refresh();
}
@Override
protected String[] getConfigLocations() {
return configLoctions;
}
}
2.2 bean前置和后置接口
beans.factory.config包
这个接口是满足于在所有的 BeanDefinition 加载完成后,实例化 Bean 对象之前,提供修改 BeanDefinition 属性的机制。
public interface BeanFactoryPostProcessor {
/*
* @Author df
* @Description 在所有的BeanDefinition加载完成后,实例化Bean对象之前,提供修改BeanDefinition属性的机制。
* 相当于在bean对象注册后没有被实例化之前进行bean的修改
* @Date 11:25 2021/11/24
* @Param []
* @return void
**/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory);
}
BeanPostProcessor:接口提供了两个方法:postProcessBeforeInitialization
用于在 Bean 对象执行初始化方法之前,执行此方法、postProcessAfterInitialization
用于在 Bean 对象执行初始化方法之后,执行此方法
// 此类可以在bean对象实例化后修改bean对象,当然也可替换对象
public interface BeanPostProcessor {
/*
* @Author df
* @Description 在bean对象执行初始化方法之前,执行此方法
* @Date 11:29 2021/11/24
* @Param [bean, beanName]
* @return java.lang.Object
**/
Object postProcessBeforeInitialization(Object bean, String beanName);
/*
* @Author df
* @Description 在bean对象执行初始化方法之后,执行此方法
* @Date 11:29 2021/11/24
* @Param [bean, beanName]
* @return java.lang.Object
**/
Object postProcessAfterInitialization(Object bean, String beanName);
}
2.3 BeanFactory类
beans.factory包下
HierarchicalBeanFactory:此类按spring中接口来写的,暂没有定义任何方法
public interface HierarchicalBeanFactory extends BeanFactory {
}
ListableBeanFactory:此接口定义了根据传进来的类进行比对bean的方法getBeansOfType(),返回注册表中所有的bean名称getBeanDefinitionNames();
// ListableBeanFactory定义了
// 1.根据指定类获取其有关系的类,2.获取所有BeanDefinition容器里的bean名称
public interface ListableBeanFactory extends BeanFactory {
// 此方法主要是为了区分哪些是自定义类,这样后续就可将自定义类方法调用即可达到想要的目的
// 从左往右,第一个T标识<T>是泛型
// 第二个T是返回Map<String,T>
// 第三个T是参数控制为泛型
<T> Map<String, T> getBeansOfType(Class<T> type);
// 返回注册表中所有的bean名称
String[] getBeanDefinitionNames();
}
ConfigurableBeanFactory:继承HierarchicalBeanFactory接口,定义了addBeanPostProcessor()方法用来添加后置bean处理
所在包:beans.factory.config
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
AutowireCapableBeanFactory:定义两个方法applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization(),供后面实现此方法
public interface AutowireCapableBeanFactory extends BeanFactory {
/*
执行BeanPostProcessor接口实现类的postProcessBeforeInitial方法
* */
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName);
/*
执行BeanPostProcessor接口实现类的postProcessAfterInitialization方法
* */
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName);
}
ConfigurableListableBeanFactory:此接口继承了ListableBeanFactory、AutowireCapableBeanFactory、ConfigurableBeanFactory ,定义了getBeanDefinition()、preInstantiateSingletons()、addBeanPostProcessor();
preInstantiateSingletons方法和addBeanPostProcessor()这两个方法在应用上下文刷新时会调用,具体的实现则在beanFactory的某个子类实现
所在包:beans.factory
/*
ConfigurableListableBeanFactory定义了:
1.根据bean名称获取BeanDefinition数据方法
2.preInstantiateSingletons()实现创建bean并存储单例bean方法
3.添加BeanPostProcessor到集合中的方法
并继承了ListableBeanFactory,AutowireCapableBeanFactory
**/
public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
// 此方法是在创建bean时需要先获取BeanDefinition时使用
BeanDefination getBeanDefinition(String beanName);
// 此方法是自定义实例化完,需要将某些对象更改的对象进行实例化
void preInstantiateSingletons();
// 此方法是在自定义类都实例化完毕,开始存储BeanPostProcessor到集合中
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
}
2.4 之前存在类修改点
AbstractAutowireCapableBeanFactory:此类修改为实现AutowireCapableBeanFactory,在创建Bean示例后添加进行后置处理方法initialization();
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 = null;
try {
bean = createBeanInstance(beanDefinition, beanName, args);
// 给 Bean 填充属性
applyPropertyValues(beanName, bean, beanDefinition);
// 执行bean的初始化方法和BeanPostProcessor的前置和后置处理方法。(都是用户自定义的哦)
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new BeansException("Instantiation of bean failed", e);
}
addSingleton(beanName, bean);
return bean;
}
protected Object createBeanInstance(BeanDefinition beanDefinition, String beanName, Object[] args) {
Constructor constructorToUse = null;
Class<?> beanClass = beanDefinition.getBeanClass();
Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();
for (Constructor ctor : declaredConstructors) {
if (null != args && ctor.getParameterTypes().length == args.length) {
constructorToUse = ctor;
break;
}
}
return getInstantiationStrategy().instantiate(beanDefinition, beanName, constructorToUse, args);
}
/**
* Bean 属性填充
*/
protected void applyPropertyValues(String beanName, Object bean, BeanDefinition beanDefinition) {
try {
PropertyValues propertyValues = beanDefinition.getPropertyValues();
for (PropertyValue propertyValue : propertyValues.getPropertyValues()) {
String name = propertyValue.getName();
Object value = propertyValue.getValue();
// 如遇到bean的引用,继续递归做bean的创建或者获取bean操作
if (value instanceof BeanReference) {
// A 依赖 B,获取 B 的实例化
BeanReference beanReference = (BeanReference) value;
value = getBean(beanReference.getBeanName());
}
// 给bean对象属性填充
BeanUtil.setFieldValue(bean, name, value);
}
} catch (Exception e) {
throw new BeansException("Error setting property values:" + beanName);
}
}
public InstantiationStrategy getInstantiationStrategy() {
return instantiationStrategy;
}
public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
this.instantiationStrategy = instantiationStrategy;
}
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) {
// 1. 执行 BeanPostProcessor Before 处理
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
// 待完成内容:invokeInitMethods(beanName, wrappedBean, beanDefinition);
invokeInitMethods(beanName, wrappedBean, beanDefinition);
// 2. 执行 BeanPostProcessor After 处理
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition) {
}
// 调用实例化后修改Bean对象方法
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (null == current) return result;
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (null == current) return result;
result = current;
}
return result;
}
}
AbstractBeanFactory:AbstractBeanFactory由原来的实现BeanFactry修改为实现ConfigurableBeanFactory,AbstractBeanFactory类的修改添加了list的全局变量,实现了addBeanPostProcessor()方法。
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}
DefaultListableBeanFactory:此类更改为添加一个实现ConfigurableListableBeanFactory接口,所以将接口里的定义方法实现,并添加如下方法
// 将bean定义数据循环取出并调用getBean方法,没被实例化则进行实例化
@Override
public void preInstantiateSingletons() throws BeansException {
// jdk8新引入的运算符-双冒号的用法,这里beanDefinitionMap.keySet()是getBean()的参数
beanDefinitionMap.keySet().forEach(this::getBean);
}
// 根据类的类型获取相关联的类信息
@Override
public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
Map<String, T> result = new HashMap<>();
// xml解析出来就放入beanDefinitionMap里,此时从beanDefinitionMap就可以找到需要的类
beanDefinitionMap.forEach((beanName, beanDefnition) -> {
Class beanClass = beanDefnition.getBeanClass();
// isAssignableFrom是判断两个类之间关系的,不是实例对象关系,是本身类,是超类,是子类,是接口类通通都是true
if (type.isAssignableFrom(beanClass)) {
// 获取bean
result.put(beanName, (T) getBean(beanName));
}
});
return result;
}
@Override
public String[] getBeanDefinitionNames() {
return beanDefinitionMap.keySet().toArray(new String[0]);
}
3.测试
3.1 事先准备工作
添加userDao,添加模拟根据id查询数据
public class UserDao {
private static Map<String, String> hashMap = new HashMap<>();
static {
hashMap.put("10001", "hahaha");
hashMap.put("10002", "ss");
hashMap.put("10003", "sio");
}
public String queryUserName(String uId) {
return hashMap.get(uId);
}
}
UserService:添加UserService类,省略set,get,你们自行添加就好,然后模拟现实service调用Dao里的方法
public class UserService {
private String uId;
private String company;
private String location;
private UserDao userDao;
public void queryUserInfo() {
System.out.println("查询用户信息:" + userDao.queryUserName(uId)
+",公司名称:"+company+",地址:"+location);
}
// ...get/set
}
3.2 添加前置后置自定义处理方法
MyBeanFactoryPostProcessor:实现BeanFactoryPostProcessor接口,也就实现了这个方法,因为是实例化之前修改,所以需要取出BeanDefination数据直接修改了
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
PropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue(new PropertyValue("company", "字节跳动"));
}
}
MyBeanPostProcessor:实现BeanPostProcessor接口,因为是已经被实例化了可以直接拿实例化后的对象进行修改。
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if ("userService".equals(beanName)) {
UserService userService = (UserService) bean;
userService.setLocation("改为:北京");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
3.3 配置文件
添加自定义修改的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<beans>
<bean id="userDao" class="com.spring.sourcecode.springframework.test.UserDao"></bean>
<bean id="userService" class="com.spring.sourcecode.springframework.test.UserService">
<property name="uId" value="10001"></property>
<property name="company" value="腾讯"></property>
<property name="location" value="深圳"></property>
<property name="userDao" ref="userDao"></property>
</bean>
<bean class="com.spring.sourcecode.springframework.beanhadel.MyBeanPostProcessor"></bean>
<bean class="com.spring.sourcecode.springframework.beanhadel.MyBeanFactoryPostProcessor"></bean>
</beans>
在测试的时候使用上下文类去操作,ClassPathXmlApplicationContext,然后就可以简化操作了
@Test
public void test_xml() {
// 1.初始化BeanFactory
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:spring.xml");
// 2.获取bean对象调用方法
UserService userService = applicationContext.getBean("userService", UserService.class);
userService.queryUserInfo();
}
既用了上下文去进行bean的操作,又加入了Bean的前置和后置操作。测试结果如下图
码字不易,点拨关注,点赞再走呗!