前语
上一节,咱们现已完结通过 xml 配置文件 完结 Bean 的注入。这一节是重头戏,老实说,我现在都还弄的很理解。这是第二遍看这个进程了,仍是有点云里雾里的。可是相对于第一次来说,现已上升了一个高度。
在这一节,会对 spring 创立 bean 的进程进行封装。而且供给 BeanPostProcessor
,BeanFactoryPostProcessor
等扩展接口。(这两个东西老强了)
上下文把整个创立进程包装起来,对外暴露一个简单的入口,其他的东西都在内部完结。(这个进程其实能够类比成 模板办法
是运用,咱们直接运用就能够,并不需要知道内部的完结)
由于上下文现已封装好了整个bean的创立进程,内部完结对外是不敞开的,所以供给了 BeanPostProcessor(bean 创立 之前处理,bean 创立之后处理)、BeanFactoryPostProcessor (对beanDifinition 创立后处理)给 开发者 的扩展接口,在创立bean的进程中,添加自己的完结逻辑。
完结
BeanPostProcessor Bean 创立完结前后扩展接口
它能够在 Bean 实例化、依赖注入、初始化前后等时刻对 Bean 进行一些额外的处理,例如修正 Bean 特点、动态署理等等。
这个类运用了模板办法
形式。扩展类只需完结该接口,然后spring会在创立的bean的进程中调用这个办法完结 对bean的修正。
spring 在获取一切的 扩展类并完结扩展运用的是装修器形式
,每个 扩展类都能够类比成一个装修器
,然后通过职责链
的办法完结调用。
**模板办法:**模板办法是一种行为规划形式,它界说了一个进程的
骨架
,并答应子类在不改变该进程结构的情况下从头界说某些步骤。 **装修器形式:**装修器形式是一种结构型规划形式,它答应动态地向目标添加新的行为,同时又不会改变其原有的行为。该形式通过一种装修器类来包装原有的类,然后给目标添加新的功能。 职责链形式:职责链形式是一种行为型规划形式,它将多个处理器(Handler)组成一条链,用于依次处理恳求,直到恳求被处理完结停止。在职责链形式中,每个处理器都有一个指向下一个处理器的引用,然后形成了一条处理链。
在实践开发进程中,咱们也能够测验运用这些规划形式来优化咱们的代码。在这个扩展接口的完结进程,咱们能够学到 模板
+装修器
+职责链
的一种运用场景。很多时分,独自是规划形式并不能很好地解决问题,可是当咱们把他们组合到一起的时分,他就会变成一种很优雅的解决方案
.
/**
* @author huangle
* @date 2023/2/13 15:18
*/
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 beanDefinition 加载完结后扩展接口
这个扩展规划跟上一个差不多,详细能够看上面的规划
public interface BeanFactoryPostProcessor {
/**
* 在一切的 BeanDefinition 加载完结后,实例化 Bean 目标之前,供给修正 BeanDefinition 特点的机制
* @param beanFactory
*/
void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory);
}
AbstractApplicationContext 一致处理抽象类
AbstractApplicationContext
完结对逻辑进程的整合,界说一致处理流程,完结进程通过界说抽象办法,交给详细的完结类去完结。
这儿其实就是对spring容器 初始化做一个 模板处理
,只界说基本骨架
,详细都交给后边的子类是完结。
public interface ConfigurableApplicationContext extends ApplicationContext{
void refresh() throws BeansException;
}
/**
* @author huangle
* @date 2023/2/13 15:15
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
/**
* 模板办法,控制界说spring上下文的刷新与创立
* @throws BeansException
*/
@Override
public void refresh() throws BeansException {
// 1. 创立beanFactory,加载beanDefinition
refreshBeanFactory();
// 2. 获取 beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 3. bean 实例化之前 履行 beanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// 4. beanPostProcessor 完结 bean 实例化后的注册操作
registerBeanPostProcessors(beanFactory);
// 5. 提早实例化 单例bean 目标
beanFactory.preInstantiateSingletons();
}
protected abstract void refreshBeanFactory() throws BeansException;
protected abstract ConfigurableListableBeanFactory getBeanFactory();
/**
* 初始化 BeanFactoryPostProcessor 处理器
* @param beanFactory
*/
private void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory){
Map<String, BeanFactoryPostProcessor> beanFactoryPostProcessorMap = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor factoryPostProcessor : beanFactoryPostProcessorMap.values()) {
// 处理 beanDifinition 扩展逻辑
factoryPostProcessor.postProcessorBeanFactory(beanFactory);
}
}
/**
* 初始化 BeanPostProcessor 处理器
* @param beanFactory
*/
private void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory){
Map<String, BeanPostProcessor> beanPostProcessorMap = beanFactory.getBeansOfType(BeanPostProcessor.class);
for (BeanPostProcessor postProcessor : beanPostProcessorMap.values()) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}
AbstractAutowireCapableBeanFactory#createBean 一致处理bean扩展逻辑
spring流程的核心类,一切的扩展都会在这儿集合,一起作用于spring创立bean的进程。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
private CglibSubclassingInstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
@Override
public Object createBean(String beanName, BeanDefinition beanDefinition, Object[] args) {
Object bean = null;
try {
bean = createBeanInstance(beanDefinition, beanName, args);
// 注入特点
applyPropertyValues(beanName, bean, beanDefinition);
// 供给给外部的扩展包装,履行 Bean 的初始化办法和 BeanPostProcessor 的前置和后置处理办法
bean = initializeBean(beanName, bean, beanDefinition);
} catch (Exception e) {
throw new RuntimeException("bean create error!", e);
}
registerSingleton(beanName, bean);
return bean;
}
private Object initializeBean(String beanName, Object bean, BeanDefinition beanDefinition) throws BeansException {
// 1. 履行 BeanPostProcess before 操作
Object wrappedBean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
invokeInitMethods(beanName,wrappedBean,beanDefinition);
// 2. 履行 BeanPostProcess after 操作
wrappedBean = applyBeanPostProcessorsAfterInitialization(bean,beanName);
return wrappedBean;
}
private void invokeInitMethods(String beanName, Object wrappedBean, BeanDefinition beanDefinition){
}
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
// 职责链形式 去获取到用户的扩展内容,然后在这儿一致去处理
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
Object current = beanPostProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanPostProcessor : getBeanPostProcessors()) {
Object current = beanPostProcessor.postProcessAfterInitialization(result, beanName);
if (current == null){
return result;
}
result = current;
}
return result;
}
}
测验
界说 MyBeanFactoryPostProcessor、MyBeanPostProcecssor 扩展内容
/**
* @author huangle
* @date 2023/3/3 15:55
*/
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessorBeanFactory(ConfigurableListableBeanFactory beanFactory) {
BeanDefinition userService = beanFactory.getBeanDefinition("userService");
PropertyValues propertyValues = userService.getPropertyValues();
PropertyValue propertyValue = new PropertyValue("nickname", "泰罗");
propertyValues.addPropertyValue(propertyValue);
}
}
/**
* @author huangle
* @date 2023/3/3 15:03
*/
public class MyBeanPostProcecssor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
UserService userService = (UserService) bean;
userService.setName("海绵宝宝");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
事务逻辑
public class UserDao {
public String getUserName(){
return "Anoxia";
}
}
public class UserService {
private String name;
private String nickname;
private UserDao userDao;
public UserService(String name) {
this.name = name;
}
public String say(){
return userDao.getUserName()+" say hello "+name + "and" + nickname;
}
}
配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="userDao" class="cn.anoxia.springframework.beans.factory.support.UserDao"/>
<bean id="userService" class="cn.anoxia.springframework.beans.factory.support.UserService">
<property name="name" value="Anoxia"/>
<property name="nickname" value="迪迦"/>
<property name="userDao" ref="userDao"/>
</bean>
<bean id="myBeanPostProcecssor" class="cn.anoxia.springframework.beans.factory.support.MyBeanPostProcecssor"/>
<bean id="myFactoryPostProcessor" class="cn.anoxia.springframework.beans.factory.support.MyBeanFactoryPostProcessor"/>
</beans>
测验类
testContext
测验 手动创立工厂、创立处理类,注入。testContext1
测验自动读取xml文件,自动注入
@Test
public void testContext() throws BeansException {
// 1. 初始化bean工厂
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 2. 界说读取xml处理器,加载bean
XmlBeanDefinitionReader definitionReader = new XmlBeanDefinitionReader(beanFactory);
definitionReader.loadBeanDefinitions("classpath:spring.xml");
// 3. BeanDefinition 加载完结 & Bean实例化之前,修正 BeanDefinition 的特点值
MyBeanFactoryPostProcessor factoryPostProcessor = new MyBeanFactoryPostProcessor();
factoryPostProcessor.postProcessorBeanFactory(beanFactory);
// 4. Bean实例化之后,修正 Bean 特点信息
MyBeanPostProcecssor postProcecssor = new MyBeanPostProcecssor();
beanFactory.addBeanPostProcessor(postProcecssor);
UserService userService = (UserService) beanFactory.getBean("userService");
System.out.println(userService.say());
}
@Test
public void testContext1() throws BeansException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
UserService userService = (UserService) applicationContext.getBean("userService");
System.out.println(userService.say());
}
测验成果
总结
这一节是学习spring进程中比较难的一节,如果学理解了这一节,对spring的扩展基本就理解了。学习的进程很枯燥,有很多时分,遇到一点问题就想抛弃,没有一追到底的意志。其实我感觉嗷,学起来累,学不理解,仍是自己会的东西太少了,导致上下连不起了,贯穿不了,导致寸步难行,继而抛弃。 怎么说呢,写代码这东西真的没有什么捷径,多写,多写,多写。只看不写,每一次有问题又是去copy,永远也不会。