BeanFactory
它是ApplicationContext的父接口
它才是Spring的核心容器,主要的ApplicationContext的实现都组合了它的功能
使用ApplicationContext的getBean方法,实际上先拿到BeanFactory对象,再去调用BeanFactory的getBean方法
BeanFactory表面上只有getBean功能实际上,控制反转,基本的依赖注入,直至Bean的生命周期都是由它的实现类提供
ApplicationContext功能
- MessageSource:处理国际化资源的能力(翻译) 比如 getMessage方法
- RessourcePatternResolver:通配符匹配资源的能力 比如 getResources方法
//表示在resources目录下的META-INF子目录下的spring.factories文件和jar包内的......
//*号表示也可以jar内进行搜索
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}
- ApplicationEventPublisher:发布事件能力 比如 publishEvent方法
//获取Component1然后进行注册
context.getBean(Component1.class).register();
//在Component1中进行声明
private static final Logger log = LoggerFactory.getLogger(Component1.class);
//该容器对象具备发送事件的功能
@Autowired
private ApplicationEventPublisher context; //事件发生器
public void register() {
log.debug("用户注册");
context.publishEvent(new UserRegisteredEvent(this));
}
//在Component2中监听该事件
private static final Logger log = LoggerFactory.getLogger(Component2.class);
@EventListener
public void aaa(UserRegisteredEvent event) {
log.debug("{}", event);
log.debug("发送短信");
}
- EnvironmentCapable:读取环境信息 比如getProperty方法
//获取properties文件和系统环境变量对应键的值
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
BeanFactory的实现
给Bean添加定义并进行注册
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// bean 的定义(class, scope, 初始化, 销毁)
AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
//注册
beanFactory.registerBeanDefinition("config", beanDefinition);
添加 BeanFactory 后处理器
// 给 BeanFactory 添加一些常用的后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//如果只是添加后处理器不进行扩展,则无法解析@Confident和@bean注解
// BeanFactory 后处理器主要功能,补充了一些 bean 定义
// getBeansOfType 根据类型获取多个bean(bean后处理器)
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); //执行beanFactory 后处理器
});
@Configuration
static class Config {
@Bean
public Bean1 bean1() {return new Bean1();}
@Bean
public Bean2 bean2() {return new Bean2();}
@Bean
public Bean3 bean3() {return new Bean3();}
@Bean
public Bean4 bean4() {return new Bean4();}
}
interface Inter { }
static class Bean3 implements Inter { }
static class Bean4 implements Inter { }
static class Bean1 {
private static final Logger log = LoggerFactory.getLogger(Bean1.class);
public Bean1() {
log.debug("构造 Bean1()");
}
@Autowired
private Bean2 bean2;
public Bean2 getBean2() {return bean2;}
//同时添加两个注解(后处理器的顺序决定了哪个先被解析)
@Autowired
@Resource(name = "bean4")
private Inter bean3;
public Inter getInter() {return bean3;}}
static class Bean2 {
private static final Logger log = LoggerFactory.getLogger(Bean2.class);
public Bean2() {
log.debug("构造 Bean2()");
}
}
添加 Bean 后处理器
// Bean 后处理器, 针对 bean 的生命周期的各个阶段提供扩展, 例如 @Autowired @Resource ...
beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
.forEach(beanPostProcessor -> {
beanFactory.addBeanPostProcessor(beanPostProcessor); //建立Bean工厂和后处理器的关系
});
后处理器器顺序
//默认是Common的后处理器排在前面,Autowired的排在后面
System.out.println("Common:" + (Ordered.LOWEST_PRECEDENCE - 3));
System.out.println("Autowired:" + (Ordered.LOWEST_PRECEDENCE - 2));
总结
BeanFactory总结:
- 不会主动调用 BeanFactory 后处理器
- 不会主动添加 Bean 后处理器
- 不会主动初始化单例
- 不会解析beanFactory 还不会解析 ${ } 与 #{ }
Bean后处理器会有排序的逻辑
ApplicationContext的实现
ClassPathXmlApplicationContext
在类路径下读取XML配置文件
private static void testClassPathXmlApplicationContext() {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("a02.xml");
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
System.out.println(context.getBean(Bean2.class).getBean1());
/**
* 结果:
* bean1
* bean2
* com.itheima.a02.A02$Bean1@6392827e
*/
}
//a02.xml
<!-- 控制反转, 让 bean1和bean2 被 Spring 容器管理 -->
<bean id="bean1" class="com.itheima.a02.A02.Bean1"/>
<bean id="bean2" class="com.itheima.a02.A02.Bean2">
<!-- 依赖注入, 让 bean2 建立与 bean1 的依赖关系 -->
<property name="bean1" ref="bean1"/>
</bean>
FileSystemXmlApplicationContext
在磁盘路径下读取XML配置文件
private static void testFileSystemXmlApplicationContext() {
FileSystemXmlApplicationContext context =
new FileSystemXmlApplicationContext("src\\main\\resources\\a02.xml");
}
AnnotationConfigApplicationContext
基于java配置类来完成
一种是指定java文件配置类,另一种是指定扫描路径
private static void testAnnotationConfigApplicationContext() {
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Config.class);
}
@Configuration
static class Config {
@Bean
public Bean1 bean1() {return new Bean1();}
@Bean
public Bean2 bean2(Bean1 bean1) {
Bean2 bean2 = new Bean2();
bean2.setBean1(bean1);
return bean2;
}
}
static class Bean1 { }
static class Bean2 {
private Bean1 bean1;
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
public Bean1 getBean1() {
return bean1;
}
}
AnnotationConfigServletWebServerApplicationContext
基于 java 配置类来创建,用于 web 环境
private static void testAnnotationConfigServletWebServerApplicationContext() {
AnnotationConfigServletWebServerApplicationContext context =
new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
}
@Configuration
static class WebConfig {
@Bean //产生内嵌的 tomcat 容器
public ServletWebServerFactory servletWebServerFactory(){return new TomcatServletWebServerFactory();}
@Bean //创建 dispatcherServlet 对象
public DispatcherServlet dispatcherServlet() {return new DispatcherServlet();}
@Bean //将 dispatcherServlet 注册到tomcat容器中
public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) {
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
@Bean("/hello")
public Controller controller1() {
return (request, response) -> {
response.getWriter().print("hello");
return null;
};
}
}
Bean的生命周期
在各个阶段里都会有由bean后处理器提供的功能增强
bean的后处理器
创建前后的增强
- postProcessBeforeInstantiation
- 这里返回的对象若不为 null 会替换掉原本的 bean,并且仅会走 postProcessAfterInitialization 流程
- postProcessAfterInstantiation
- 这里如果返回 false 会跳过依赖注入阶段
依赖注入前的增强
- postProcessProperties
- 如 @Autowired、@Value、@Resource
初始化前后的增强
- postProcessBeforeInitialization
- 这里返回的对象会替换掉原本的 bean
- 如 @PostConstruct、@ConfigurationProperties
- postProcessAfterInitialization
- 这里返回的对象会替换掉原本的 bean
- 如代理增强
销毁之前的增强
- postProcessBeforeDestruction
- 如 @PreDestroy
@Component
public class MyBeanPostProcessor implements InstantiationAwareBeanPostProcessor, DestructionAwareBeanPostProcessor {
private static final Logger log = LoggerFactory.getLogger(MyBeanPostProcessor.class);
//postProcessBeforeDestruction:在销毁之前执行 bean 后处理器
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 销毁之前执行, 如 @PreDestroy");
}
//postProcessBeforeInstantiation:在实例化之前执行
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 实例化之前执行, 这里返回的对象会替换掉原本的 bean");
return null;
}
//postProcessAfterInstantiation:实例化之后执行,如果返回 false 会跳过依赖注入阶段,返回true则不会跳过
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean")) {
log.debug("<<<<<< 实例化之后执行");
}
return true;
}
//postProcessProperties:依赖注入阶段执行
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 依赖注入阶段执行, 如 @Autowired、@Value、@Resource");
return pvs;
}
//postProcessBeforeInitialization:初始化之前执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之前执行, 这里返回的对象会替换掉原本的 bean, 如 @PostConstruct、@ConfigurationProperties");
return bean;
}
//postProcessAfterInitialization:初始化之后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("lifeCycleBean"))
log.debug("<<<<<< 初始化之后执行, 这里返回的对象会替换掉原本的 bean, 如代理增强");
return bean;
}
}
模板方法设计模式
public static void main(String[] args) {
MyBeanFactory beanFactory = new MyBeanFactory();
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Autowired"));
beanFactory.addBeanPostProcessor(bean -> System.out.println("解析 @Resource"));
beanFactory.getBean();
}
static class MyBeanFactory {
public Object getBean() {
Object bean = new Object();
System.out.println("构造 " + bean);
System.out.println("依赖注入 " + bean); // @Autowired, @Resource
for (BeanPostProcessor processor : processors) {
processor.inject(bean);
}
System.out.println("初始化 " + bean);
return bean;
}
private List<BeanPostProcessor> processors = new ArrayList<>(); //后处理器集合
public void addBeanPostProcessor(BeanPostProcessor processor) {processors.add(processor);}
}
static interface BeanPostProcessor {
public void inject(Object bean); // 对依赖注入阶段的扩展
}