Spring实例化基本流程
Spring在容器初始化的时候,读取XMl配置,将其封装成BeanDefinition(Bean定义)对象,描述所有bean的信息
BeanDefinition会注册存储到beanDefinitionMap集合中
Spring框架遍历beanDefinitionMap,使用反射创建Bean实例对象
创建好之后的对象存储在singletonObjects的map集合中,当getBean时,从该map中取出实例bean对象返回
Spring配置文件中的配置项都能在BeanDefinition对象中找到
BeanDefinition是一个接口,我们使用RootBeanDefinition即可
Spring中的两个后处理器
Spring中提供两个后处理器,让我们能够介入实例化流程,动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用
BeanFactoryPostProcessor:Bean工厂后处理器,在beanDefinitionMap填充完毕,还未反射创建对象之前执行
BeanPostProcessor:Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变,有一个before和after,中间隔着初始化方法的执行。
一个在还未创建对象之前,一个在创建对象之后
Bean工厂后处理器 BeanFactoryPostProcessor
BeanFactoryPostProcessor是一个接口,实现了该接口的类只要交由spring容器管理的话,那么spring就会回调该接口的方法,用于对BeanDefinition注册和修改
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyBeanFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
System.out.println("BeanDefinitionMap填充完毕之后执行该方法");
// 创建一个BeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
// 查看继承关系图ConfigurableListableBeanFactory就是DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
// 注册Bean
defaultListableBeanFactory.registerBeanDefinition("userService",rootBeanDefinition);
}
}
<bean id="userService" name="aaa,bbb" class="com.tech.test.service.impl.UserServiceImpl" ></bean>
<bean class="com.tech.test.processor.MyBeanFactoryProcessor "></bean>
需要在配置文件中配置交给spring管理,这个示例 我们动态的修改对象userService为DI对象,当我们getBean时,Bean已经被修改为DI对象
spring提供了专门注册BeanDefinitionMap的接口,BeanDefinitionRegistryPostProcessor,看下继承关系,它是BeanFactoryPostProcessor 的子接口
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.beans.factory.support;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}
演示相同功能
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyNoCastProcessor implements BeanDefinitionRegistryPostProcessor {
// 执行顺序早于postProcessBeanFactory 简记为 谁在上边谁先执行
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 创建一个BeanDefinition
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClassName("com.tech.test.test.bean.DI");
// 注册Bean
beanDefinitionRegistry.registerBeanDefinition("userService",rootBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
<bean id="userService" name="aaa,bbb" class="com.tech.test.service.impl.UserServiceImpl" ></bean>
<bean id="process" class="com.tech.test.processor.MyNoCastProcessor"></bean>
示例:定义自定义注解实现注册对象,配置就不列举啦,需要在对象未创建之前加入Bean定义信息
自定义注解
package com.tech.test.anotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyComponent {
String value();
}
加上注解
package com.tech.test.testbean;
import com.tech.test.anotation.MyComponent;
@MyComponent("ceshi")
public class TestAnnotation {
}
解析注解
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class ParseMyComponentProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
// 这里的全限定类名和注解中的名称应该扫描包得到,这里暂时写死
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClassName("com.tech.test.testbean.TestAnnotation");
beanDefinitionRegistry.registerBeanDefinition("ceshi",rootBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
}
}
测试注解
package com.tech.test.springtest;
import com.tech.test.testbean.DI;
import com.tech.test.testbean.TestAnnotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestParseAnnotation {
public static void main(String[] args) {
// 创建ApplicationContext,加载配置文件,实例化容器
ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 获取Bean
TestAnnotation testAnnotation = classPathXmlApplicationContext.getBean(TestAnnotation.class);
System.out.println(testAnnotation);
}
}
Bean后处理器BeanPostProcessor
Bean后处理器 ,在Bean实例化之后,填充至singletonObjects之前执行,一但添加至singletonObjects意味着不能改变
示例:为spring中的Bean执行方法添加时间,执行开始之前加入时间,执行之后加入时间,这里使用jdk动态代理做增强
package com.tech.test.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.lang.reflect.Proxy;
import java.util.Date;
public class MyBeanProcessor implements BeanPostProcessor {
// before 和after之间隔着InitliazeBean初始化的执行过程
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Object proxyBean = Proxy.newProxyInstance(
bean.getClass().getClassLoader(),
bean.getClass().getInterfaces(),
(proxy, method, args) -> {
System.out.println("方法" + method.getName() + "开始时间" + new Date());
// 执行目标方法
Object invoke = method.invoke(bean, args);
System.out.println("方法" + method.getName() + "结束时间" + new Date());
return invoke;
});
return proxyBean;
}
}
<bean class="com.tech.test.processor.MyBeanProcessor"></bean>
测试结果
package com.tech.test.springtest;
import com.tech.test.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestApplicationContext {
public static void main(String[] args) {
ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService =(UserService) classPathXmlApplicationContext.getBean("userService");
userService.getUser();
}
}