上回书说到加载配置文件中的配置信息自动注册到bean工厂里,这次我们再将他整合起来,一步到位,顺便扩展一下功能.
后处理器进行扩展
BeanPostProcessor
package com.linnine.spring.beans.factory.config;
import com.linnine.spring.beans.BeansException;
/**
* bean后处理器
*/
public interface BeanPostProcessor {
/**
* bean对象初始化前执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
Object postProcessBeforeInitialization(Object bean,String beanName)throws BeansException;
/**
* bean 对象初始化后执行
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
Object postProcessAfterInitialization(Object bean,String beanName)throws BeansException;
}
BeanFactoryPostProcessor
package com.linnine.spring.beans.factory.config;
import com.linnine.spring.beans.factory.ConfigurableListableBeanFactory;
/**
* bean工厂后处理器
*/
public interface BeanFactoryPostProcessor {
/**
* 对工厂进行一些扩展
* @param beanFactory
*/
void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory);
}
定义上下文接口
ApplicationContext
后面再补充
package com.linnine.spring.context;
import com.linnine.spring.beans.factory.ListableBeanFactory;
/**
* 上下文接口
*/
public interface ApplicationContext extends ListableBeanFactory {
}
逐步完善上下文
ConfigurableApplicationContext
package com.linnine.spring.context;
import com.linnine.spring.beans.BeansException;
public interface ConfigurableApplicationContext extends ApplicationContext{
/**
* 刷新容器
* @throws BeansException
*/
void refresh() throws BeansException;
}
AbstractApplicationContext
抽象类实现部分功能
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();
//在Bean实例化前 调用后处理器
invokeBeanFactoryPostProcessors(beanFactory);
//注册bean处理器
registerBeanPostProcessors(beanFactory);
//提前实例化单例对象
beanFactory.preInstantiateSingletons();
}
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//获取所有工厂后处理器
Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
//遍历去处理
for (BeanFactoryPostProcessor beanFactoryPostProcessor : beanFactoryPostProcessorMap.values()) {
beanFactoryPostProcessor.postProcessorBeanFactory(beanFactory);
}
}
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor beanPostProcessor : beanPostProcessorMap.values()) {
beanFactory.addBeanPostProcessor(beanPostProcessor);
}
}
protected abstract ConfigurableListableBeanFactory getBeanFactory();
protected abstract void refreshBeanFactory();
}
AbstractRefreshableApplicationContext
继续扩展,但又有抽象方法, 是不是后面需要扩展的时候,直接加抽象方法,不去实现,尽量不改变原来的功能
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.support.DefaultListableBeanFactory;
import java.util.Map;
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext{
private DefaultListableBeanFactory beanFactory;
public AbstractRefreshableApplicationContext() {
this.beanFactory = createBeanFactory();
}
/**
* 刷新
*/
@Override
protected void refreshBeanFactory() {
//直接重新创建
DefaultListableBeanFactory beanFactory = createBeanFactory();
//重新加载
loadBeanDefinitions(beanFactory);
this.beanFactory=beanFactory;
}
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory);
private DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory();
}
@Override
protected ConfigurableListableBeanFactory getBeanFactory() {
return beanFactory;
}
public Object getBean(String beanName,Object... args){
return beanFactory.getBean(beanName,args);
}
public <T> Map<String, T> getBeansOfType(Class<T> var1) throws BeansException {
return beanFactory.getBeansOfType(var1);
}
public <T> Map<String, T> getBeansOfType(Class<T> var1, boolean var2, boolean var3) throws BeansException {
return beanFactory.getBeansOfType(var1,var2,var3);
}
}
AbstractXmlApplicationContext
继续用一个抽象类实现一部分功能
package com.linnine.spring.context.support;
import com.linnine.spring.beans.factory.support.DefaultListableBeanFactory;
import com.linnine.spring.beans.factory.xml.XmlBeanDefinitionReader;
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableApplicationContext{
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory, this);
String[] configLocations = getConfigLocations();
if (null!=configLocations){
beanDefinitionReader.loadBeanDefinitions(configLocations);
}
}
protected abstract String[] getConfigLocations();
}
ClassPathXmlApplicationContext
终于到底了
package com.linnine.spring.context.support;
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext{
private String[] configLocations;
public ClassPathXmlApplicationContext() {
}
public ClassPathXmlApplicationContext(String... configLocations) {
this.configLocations = configLocations;
//刷新容器
refresh();
}
@Override
protected String[] getConfigLocations() {
return configLocations;
}
}
自定义后处理器
MyBeanPostProcessor
然后手撸一个自定义的Bean处理器
package com.linnine.spring.common;
import com.linnine.spring.bean.service.UserService;
import com.linnine.spring.beans.BeansException;
import com.linnine.spring.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)){
UserService userService = (UserService) bean;
userService.setLocation("改为:北京");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
MyBeanFactoryPostProcessor
手撸一个自定义BeanFactory后处理器
package com.linnine.spring.common;
import com.linnine.spring.beans.PropertyValue;
import com.linnine.spring.beans.PropertyValues;
import com.linnine.spring.beans.factory.ConfigurableListableBeanFactory;
import com.linnine.spring.beans.factory.config.BeanDefinition;
import com.linnine.spring.beans.factory.config.BeanFactoryPostProcessor;
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userService");
PropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue(new PropertyValue("company","改为:字节跳动"));
}
}
代码测试
/**
* 后处理器的调用流程
*/
@Test
public void testPostProcessor(){
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("classpath:spring.xml");
MyBeanFactoryPostProcessor beanFactoryPostProcessor = new MyBeanFactoryPostProcessor();
beanFactoryPostProcessor.postProcessorBeanFactory(beanFactory);
MyBeanPostProcessor beanPostProcessor = new MyBeanPostProcessor();
beanFactory.addBeanPostProcessor(beanPostProcessor);
UserService userService = (UserService) beanFactory.getBean("userService", UserService.class);
String s = userService.queryUserInfo();
System.out.println("测试结果:"+s);
}
/**
* 自动调用后处理器
*/
@Test
public void test133(){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
UserService userService = (UserService)applicationContext.getBean("userService", UserService.class);
String s = userService.queryUserInfo();
System.out.println(s);
}