珠海市建设工程质量监督检测站网站,网站建设找客户渠道,wordpress免签约微信支付宝,如何做电影网站资源打印启动信息 转载自:www.javaman.cn 1 spring Bean实例化流程
基本流程#xff1a;
1、Spring容器在进行初始化时#xff0c;会将xml或者annotation配置的bean的信息封装成一个BeanDefinition对象#xff08;每一个bean标签或者bean注解都封装成一个BeanDefinition对象
1、Spring容器在进行初始化时会将xml或者annotation配置的bean的信息封装成一个BeanDefinition对象每一个bean标签或者bean注解都封装成一个BeanDefinition对象所有的BeanDefinition存储到一个名为beanDefinitionMap的Map集合中去
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {private final MapString, BeanDefinition beanDefinitionMap;···this.beanDefinitionMap.put(beanName, beanDefinition);
}2、Spring框架在对该Map进行遍历使用反射创建Bean实例对象创建好的Bean对象存储在一个名为singletonObjects单例池的Map集合中当调用getBean方法时则最终从该Map集合中取出Bean实例对象返回
public class DefaultSingletonBeanRegistry extends ... implements ... {//存储Bean实例的单例池//key:是Bean的beanNamevalue:是Bean的实例对象private final MapString, Object singletonObjects new ConcurrentHashMap(256);//注册beanpublic void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {Assert.notNull(beanName, Bean name must not be null);Assert.notNull(singletonObject, Singleton object must not be null);synchronized(this.singletonObjects) {Object oldObject this.singletonObjects.get(beanName);if (oldObject ! null) {throw new IllegalStateException(Could not register object [ singletonObject ] under bean name beanName : there is already object [ oldObject ] bound);} else {this.addSingleton(beanName, singletonObject);}}}}
总体流程如下
加载xml配置文件解析获取配置中的每个的信息封装成一个个的BeanDefinition对象;将BeanDefinition存储在一个名为beanDefinitionMap的Map中;ApplicationContext底层遍历beanDefinitionMap反射创建Bean实例对象;创建好的Bean实例对象被存储到一个名为singletonObjects的Map中;当执行applicationContext.getBean(beanName)时从singletonObjects去匹配Bean实例返回
2 Spring的后处理器
Spring的后处理器是Spring对外开发的重要扩展点允许我们介入到Bean的整个实例化流程中来以达到动态注册BeanDefinition动态修改BeanDefinition以及动态修改Bean的作用。Spring主要有两种后处理器 BeanFactoryPostProcessorBean工厂后处理器在BeanDefinitionMap填充完毕Bean实例化之前执行 BeanPostProcessorBean后处理器一般在Bean实例化之后填充到单例池singletonObjects之前执行。
3 实现BeanFactoryPostProcessor接口创建SpringUtils工具类
实现了 BeanFactoryPostProcessor 接口。这意味着它可以在Spring容器加载Bean定义后在实例化Bean之前对BeanFactory进行自定义的处理
创建SpringUtils工具类提供了一些静态方法以便在应用程序中更方便地获取和操作Spring容器中的Bean
package com.ds.core.util;import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;Component
public final class SpringUtils implements BeanFactoryPostProcessor {//1、存储Spring应用上下文的Bean工厂,在postProcessBeanFactory方法中初始化//2、静态的 ConfigurableListableBeanFactory 类型的变量 beanFactory用于存储Spring应用上下文的Bean工厂private static ConfigurableListableBeanFactory beanFactory;Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {SpringUtils.beanFactory configurableListableBeanFactory;}/*** 根据名称获取bean** param name* param T* return*/public static T T getBean(String name) throws BeansException {return (T) beanFactory.getBean(name);}/*** 根据类型获取bean* param clz* param T* return* throws BeansException*/public static T T getBean(ClassT clz) throws BeansException {return (T) beanFactory.getBean(clz);}/*** 检查是否存在具有指定名称的Bean。如果存在它返回true否则返回false。* param name* return*/public static boolean containsBean(String name){return beanFactory.containsBean(name);}/***判断一个Bean是否是单例的在Spring中只有一个实例* param name* return* throws NoSuchBeanDefinitionException*/public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {return beanFactory.isSingleton(name);}/*** 获取指定名称的Bean的类型* param name* return* throws NoSuchBeanDefinitionException*/public static Class? getType(String name) throws NoSuchBeanDefinitionException{return beanFactory.getType(name);}/*** 获取aop代理对象** param invoker* return*/SuppressWarnings(unchecked)public static T T getAopProxy(T invoker){return (T) AopContext.currentProxy();}}
4 实现ApplicationListener监听 Web 服务器初始化事件
实现了 ApplicationListenerWebServerInitializedEvent 接口意味着它监听应用程序事件特别是监听 Web 服务器初始化事件。重写的方法 onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent)。当 Web 服务器初始化事件发生时这个方法会被触发。在这个方法内部通过传入的 WebServerInitializedEvent 对象获取到正在运行的服务器的端口号并将其赋值给 serverPort 变量从而获取服务器的URL地址。
Component
public class ServerConfig implements ApplicationListenerWebServerInitializedEvent{private int serverPort;public String getUrl(){InetAddress address null;try {address InetAddress.getLocalHost();} catch (UnknownHostException e) {e.printStackTrace();}return http://address.getHostAddress():this.serverPort;}Overridepublic void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) {this.serverPort webServerInitializedEvent.getWebServer().getPort();}}5 启动添加日志信息
Slf4j
SpringBootApplication
EnableAspectJAutoProxy(exposeProxy true)
public class BookApplication {public static void main(String[] args) {SpringApplication.run(BookApplication.class,args);printUrl();}private static void printUrl() {//获取ServerConfig.class//因为是私有方法所以无法通过Autowired注入,通过ServerConfig serverConfig SpringUtils.getBean(ServerConfig.class);log.info(\n----------------------------------------------------------\n\t Application is running! Access URLs:\n\t 访问网址: serverConfig.getUrl() \n ----------------------------------------------------------);}
}运行如下图