这里写目录标题
BeanFactory与ApplicationContext
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
/**
* 1 . 到底什么是BeanFactory
* - 它是ApplicationContext的父接口
* - 它才是Spring的核心容器,主要的ApplicationContext都组合了它的功能
*/
System.out.println(context);
/**
* 2. BeanFactory 能干什么
* - 表面上只有 getBean
* - 实际上控制反转、基本的依赖注入,直至Bean的生命周期的各种功能,都是由它的实现类提供
*/
Field singletonFactories = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonFactories.setAccessible(true);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Map<String,Object> map = (Map<String, Object>) singletonFactories.get(beanFactory);
System.out.println(map);
/**
* 3 . ApplicationContext 比 BeanFactory 多点啥
*
*/
// - MessageSource 国际化,通过浏览器请求头带过来(getMessage)
// - ResourcePatternResolver 获取资源(file,获取磁盘下的资源,classpath,获取类路径下的资源,classpath*,获取类路径和jar包中的资源)
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}
// - PropertyResolver 获取环境变量
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
// - ApplicationEventPublisher 发布事件,实现组件之间的解耦
PublishEvent bean = context.getBean(PublishEvent.class);
bean.register();
}
}
发布事件
事件发布
public class UserRegisterEvent extends ApplicationEvent {
public UserRegisterEvent(Object source) {
super(source);
}
}
@Component
public class PublishEvent {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
public void register(){
System.err.println("用户注册");
applicationEventPublisher.publishEvent(new UserRegisterEvent("用户注册事件"));
}
}
事件监听
@Component
public class ListenerEvent {
@EventListener
public void listener(UserRegisterEvent userRegisterEvent){
System.err.println("listener "+userRegisterEvent.getSource()+ " 发短信");
}
}
BeanFactory 的实现DefaultListableBeanFactory
BeanFactory 处理器
public class DefaultListBeanFactoryDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 定义 bean 并注册到 beanFactory
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(BeanConfig.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("beanConfig",beanDefinition);
// 可以发现 @Configuration @Bean 注解并没有识别
// 给beanFactory添加 bean工厂后处理器,并执行后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().
forEach(beanFactoryPostProcessor ->beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
@Configuration
static class BeanConfig{
@Bean
public Bean1 bean1(){
return new Bean1();
}
@Bean
public Bean2 bean2(){
return new Bean2();
}
}
static class Bean1{
public Bean1(){
System.out.println("Bean11111");
}
}
static class Bean2{
public Bean2(){
System.out.println("Bean11111");
}
}
}
Bean 处理器
public class DefaultListBeanFactoryDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 定义 bean 并注册到 beanFactory
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(BeanConfig.class).setScope("singleton").getBeanDefinition();
beanFactory.registerBeanDefinition("beanConfig",beanDefinition);
// 可以发现 @Configuration @Bean 注解并没有识别
// 给beanFactory添加后处理器,并执行后处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().
forEach(beanFactoryPostProcessor ->beanFactoryPostProcessor.postProcessBeanFactory(beanFactory));
// Bean1 bean = beanFactory.getBean(Bean1.class);
// System.out.println(bean.bean2());
// 并未识别到 @Autowire 注解 ?
// Bean 后处理器,针对bean的生命周期的各个阶段提供扩展,例如 @Autowire @Resoure ...
beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);
// 预先把所有的单例对象 加载后好 而不是用到在加载
beanFactory.preInstantiateSingletons();
System.out.println(">>>>>>>>>>>>>>>>>");
Bean1 bean = beanFactory.getBean(Bean1.class);
bean.bean2();
}
@Configuration
static class BeanConfig{
@Bean
public Bean1 bean1(){
return new Bean1();
}
@Bean
public Bean2 bean2(){
return new Bean2();
}
}
static class Bean1{
public Bean1(){
System.out.println("Bean11111");
}
@Autowired
private Bean2 bean2;
public Bean2 bean2(){
return bean2;
}
}
static class Bean2{
public Bean2(){
System.out.println("Bean2222");
}
}
}
拓展:
当一个接口有多个实现类,把接口注入时,既使用@Autowire 也使用 @Resource 是优先使用谁注入?
这个与 Bean 处理器 被运行的先后顺序有关 ,可以控制
get:
a. beanFactory不会做的事
1. 不会主动调用 BeanFactory 后处理器 2. 不会主动添加 Bean 后处理器 3. 不会主动初始化单例 4. 不会解析 beanFactory 还不会解析 ${} 与 #{}
b. bean 后处理器会有排序的逻辑
ApplicationContext 实现
package com.zhj;
import com.zhj.demo.DefaultListBeanFactoryDemo;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.rowset.spi.XmlReader;
import java.lang.annotation.Annotation;
public class TestBeanFactory {
public static void main(String[] args) {
// testClassPathXmlApplicationContext();
// testFileSystemXmlApplicationContext();
/**
* 上面两个方法的原理
*/
/**
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
System.out.println("读取之前");
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
// reader.loadBeanDefinitions(new ClassPathResource("b01.xml"));
reader.loadBeanDefinitions(new FileSystemResource("src/main/resources/b01.xml"));
System.out.println("读取之后");
for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
*/
// testAnnotationConfigApplicationContext(); // 自动配置了后处理器
testAnnotationConfigServletApplicationContext(); // 运行访问 http://localhost:8080/hello
}
static void testClassPathXmlApplicationContext() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("b01.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
;
static void testFileSystemXmlApplicationContext() {
FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("src/main/resources/b01.xml");
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
;
static void testAnnotationConfigApplicationContext() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
for (String beanDefinitionName : context.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
;
static void testAnnotationConfigServletApplicationContext() {
AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
}
@Configuration
static class WebConfig{
@Bean
public ServletWebServerFactory servletWebServerFactory(){
return new TomcatServletWebServerFactory();
}
@Bean
public DispatcherServlet dispatcherServlet(){
return new DispatcherServlet();
}
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistrationBean(DispatcherServlet dispatcherServlet){
return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
}
@Bean("/hello") // Controller 是spring提供的一个接口
public Controller controller(){
return (httpServletRequest, httpServletResponse) -> {
httpServletResponse.getWriter().write("hello");
return null;
};
}
}
@Configuration
static class Config{
@Bean
public Bean1 bean1(){
Bean1 bean1 = new Bean1();
return bean1;
}
@Bean
public Bean2 bean2(Bean1 bean1){
Bean2 bean2 = new Bean2();
bean2.setBean1(bean1);
return bean2;
}
}
static class Bean1{
public Bean1(){
System.out.println("111");
}
}
static class Bean2{
public Bean2(){
System.out.println("222");
}
private Bean1 bean1;
public void setBean1(Bean1 bean1) {
this.bean1 = bean1;
}
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<bean id="bean2" class="com.zhj.demo.DefaultListBeanFactoryDemo.Bean2"></bean>
<bean id="bean1" class="com.zhj.demo.DefaultListBeanFactoryDemo.Bean1">
<property name="bean2" ref="bean2"></property>
</bean>
<!-- 添加后处理器 -->
<context:annotation-config/>
</beans>