当前位置: 首页> 游戏> 手游 > 成人大专学校有哪些学校_抖音代运营服务内容_搜索引擎入口yandex_今日新闻头条官网

成人大专学校有哪些学校_抖音代运营服务内容_搜索引擎入口yandex_今日新闻头条官网

时间:2025/7/29 10:11:02来源:https://blog.csdn.net/qq_74092815/article/details/147088320 浏览次数:0次
成人大专学校有哪些学校_抖音代运营服务内容_搜索引擎入口yandex_今日新闻头条官网

 

目录

Spring中工厂模式的应用

Spring设计理念

Spring中Bean组件定义相关

BeanFactory源码&使用情景

Spring中的FactoryBean

为什么需要FactoryBean?

FactoryBean的使用特点?

使用场景

BeanFactory与FactoryBean区别

BeanFactory和ApplicationContext的区别

Spring中观察者模式应用

Spring中观察者模式

事件机制工作流程

监听器什么时候注册到IOC容器

Spring如何发布的事件并通知监听者


Spring设计模式内容,读者如果阅读过 自己实现Spring简易版解析 或许有不一样的感受哦

Spring中工厂模式的应用

Spring设计理念

  • Spring是面向Bean的编程(BOP:Bean Oriented Programming),Bean在Spring中才是真正的主角。Bean在Spring中作用就像Object对OOP的意义一样,没有对象的概念就像没有面向对象编程,Spring中没有Bean也就没有Spring存在的意义。Spring提供了IoC 容器通过配置文件或者注解的方式来管理对象之间的依赖关系。

  • 控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。

Spring中Bean组件定义相关

  • Bean的定义 解析Bean的配置信息,封装到BeanDefinition中

  • Bean的创建 使用反射创建bean对象 id

  • Bean的解析 赋值、初始化等操作。

Spring Bean的创建是典型的工厂模式,它的顶级接口是BeanFactory。

职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

BeanFactory有三个子类:ListableBeanFactory、HierarchicalBeanFactory和AutowireCapableBeanFactory。目的是为了区分Spring内部对象处理和转化的数据限制

但从图中可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口。

Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得Bean对象

BeanFactory,以Factory结尾,表示它是一个工厂(接口), 它负责生产和管理bean的一个工厂。在Spring中,BeanFactory是工厂的顶层接口,也是IOC容器的核心接口,因此BeanFactory中定义了管理Bean的通用方法,如 getBeancontainsBean 等.

BeanFactory只是个接口,并不是IOC容器的具体实现,所以Spring容器给出了很多种实现,如 DefaultListableBeanFactoryXmlBeanFactoryApplicationContext等,其中XmlBeanFactory就是常用的一个,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。

BeanFactory源码&使用情景

  • 从IOC容器中获取Bean(Name or Type)

  • 检索IOC容器中是否包含了指定的对象

  • 判断Bean是否为单例

public interface BeanFactory {/**对FactoryBean的转移定义,因为如果使用bean的名字来检索FactoryBean得到的是对象是工厂生成的对象,如果想得到工厂本身就需要转移*/String FACTORY_BEAN_PREFIX = "&";//根据Bean的名字 获取IOC容器中对应的实例Object getBean(String var1) throws BeansException;//根据Bean的名字和class类型得到bean实例,增加了类型安全验证机制<T> T getBean(String var1, Class<T> var2) throws BeansException;Object getBean(String var1, Object... var2) throws BeansException;<T> T getBean(Class<T> var1) throws BeansException;<T> T getBean(Class<T> var1, Object... var2) throws BeansException;<T> ObjectProvider<T> getBeanProvider(Class<T> var1);<T> ObjectProvider<T> getBeanProvider(ResolvableType var1);//查看Bean容器中是否存在对应的实例,存在返回true 否则返回falseboolean containsBean(String var1);//根据Bean的名字 判断这个bean是不是单例boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;//得到bean实例的class类型@NullableClass<?> getType(String var1) throws NoSuchBeanDefinitionException;@NullableClass<?> getType(String var1, boolean var2) throws NoSuchBeanDefinitionException;    //得到bean的别名String[] getAliases(String var1);
}

Spring中的FactoryBean

FactoryBean是一个Bean,但又不仅仅是一个Bean,这样听起来矛盾,但为啥又这样说呢?其实在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个FactoryBean不是简单的Bean,而是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂方法模式和装饰器模式类似

public interface FactoryBean<T> {String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";/**getObject()方法: 会返回该FactoryBean生产的对象实例,我们需要实现该方法,以给出自己的对象实例化逻辑这个方法也是FactoryBean的核心.*/@NullableT getObject() throws Exception;/**getObjectType()方法: 仅返回getObject() 方法所返回的对象类型,如果预先无法确定,返回NULL,这个方法返回类型是在IOC容器中getBean所匹配的类型*/@NullableClass<?> getObjectType();//该方法的结果用于表明 工厂方法getObject() 所生产的 对象是否要以单例形式存储在容器中如果以单例存在就返回true,否则返回falsedefault boolean isSingleton() {return true;}
}

为什么需要FactoryBean?

  • 在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。

  • 由于第三方库不能直接注册到spring容器,于是可以实现org.springframework.bean.factory.FactoryBean接口,然后给出自己对象的实例化代码即可。

FactoryBean的使用特点?

  • 当用户使用容器本身时,可以使用转义字符"&"来得到FactoryBean本身,以区别通过FactoryBean产生的实例对象和FactoryBean对象本身。

FactoryBean表现的是一个工厂的职责,如果一个BeanA 是实现FactoryBean接口,那么A就是变成了一个工厂,根据A的名称获取到的实际上是工厂调用getObject()方法返回的对象,而不是对象本身,如果想获取工厂对象本身,需要在名称前面加上 '&'符号

  • getObject('name') 返回的是工厂中工厂方法生产的实例

  • getObject('&name') 返回的是工厂本身实例

使用场景

  • FactoryBean的最为经典的使用场景,就是用来创建AOP代理对象,这个对象在Spring中就是 ProxyFactoryBean

BeanFactory与FactoryBean区别

  • 他们两个都是工厂,但是FactoryBean本质还是一个Bean,也归BeanFactory管理

  • BeanFactory是Spring容器的顶层接口,FactoryBean更类似于用户自定义的工厂接口

BeanFactory和ApplicationContext的区别

  • BeanFactory是Spring容器的顶层接口,而ApplicationContext应用上下文类 他是BeanFactory的子类,他是Spring中更高级的容器,提供了更多的功能

    • 国际化

    • 访问资源

    • 载入多个上下文

    • 消息发送 响应机制

  • 两者的装载bean的时机不同

    • BeanFactory: 在系统启动的时候不会去实例化bean,只有从容器中拿bean的时候才会去实例化(懒加载)

      • 优点: 应用启动的时候占用的资源比较少,对资源的使用要求比较高的应用 ,比较有优势

    • ApplicationContext:在启动的时候就把所有的Bean全部实例化。

      • lazy-init= true 可以使bean延时实例化

      • 优点: 所有的Bean在启动的时候就加载,系统运行的速度快,还可以及时的发现系统中配置的问题。

Spring中观察者模式应用

观察者模式(发布-订阅(Publish/Subscribe)模式)它是用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应的作出反应。

在观察者模式中发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以应对多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展。

观察者和被观察者,是松耦合的关系;发布者和订阅者,则完全不存在耦合。

  • 在设计模式结构上,发布订阅模式继承自观察者模式,是观察者模式的一种实现的变体。

  • 在设计模式意图上,两者关注点不同,一个关心数据源,一个关心的是事件消息。

    • 观察者模式:数据源直接通知订阅者发生改变。

    • 发布订阅模式:数据源告诉第三方(事件通道)发生了改变,第三方再通知订阅者发生了改变。

Spring中观察者模式

Spring 基于观察者模式,实现了自身的事件机制也就是事件驱动模型,事件驱动模型通常也被理解成观察者或者发布/订阅模型。

Spring事件模型提供如下几个角色

  • 【事件】ApplicationEvent:是所有事件对象的父类。ApplicationEvent 继承自 jdk 的 EventObject, 所有的事件都需要继承 ApplicationEvent, 并且通过 source 得到事件源。

    • ContextRefreshEvent,当ApplicationContext容器初始化完成或者被刷新的时候,就会发布该事件。

    • ContextStartedEvent,当ApplicationContext启动的时候发布事件.

    • ContextStoppedEvent,当ApplicationContext容器停止的时候发布事件.

    • RequestHandledEvent,只能用于DispatcherServlet的web应用,Spring处理用户请求结束后,系统会触发该事件。

  • 【事件监听】ApplicationListener:

    • ApplicationListener(应用程序事件监听器) 继承自jdk的EventListener,所有的监听器都要实现这个接口,这个接口只有一个onApplicationEvent()方法,该方法接受一个ApplicationEvent或其子类对象作为参数

    • 在方法体中,可以通过不同对Event类的判断来进行相应的处理.当事件触发时所有的监听器都会收到消息,如果你需要对监听器的接收顺序有要求,可是实现该接口的一个实现SmartApplicationListener,通过这个接口可以指定监听器接收事件的顺序。

    • 实现了ApplicationListener接口之后,需要实现方法onApplicationEvent(),在容器将所有的Bean都初始化完成之后,就会执行该方法。

  • 【事件源】ApplicationEventPublisher:事件的发布者,封装了事件发布功能方法接口,是Applicationcontext接口的超类

    • 事件机制的实现需要三个部分,事件源,事件,事件监听器,ApplicationEvent就相当于事件,ApplicationListener相当于事件监听器,ApplicationEventPublisher相当于时间源。

    • 我们常用的ApplicationContext都继承了AbstractApplicationContext,像我们平时常见ClassPathXmlApplicationContext、XmlWebApplicationContex也都是继承了它,AbstractApplicationcontext是ApplicationContext接口的抽象实现类,在该类中实现了publishEvent方法

  • 【事件管理】ApplicationEventMulticaster:用于事件监听器的注册和事件的广播。监听器的注册就是通过它来实现的,它的作用是把 Applicationcontext 发布的 Event 广播给它的监听器列表。

    public interface ApplicationEventMulticaster {//添加事件监听器void addApplicationListener(ApplicationListener<?> var1);//添加事件监听器,使用容器中的beanvoid addApplicationListenerBean(String var1);//移除事件监听器void removeApplicationListener(ApplicationListener<?> var1);void removeApplicationListenerBean(String var1);//移除所有void removeAllListeners();//发布事件void multicastEvent(ApplicationEvent var1);void multicastEvent(ApplicationEvent var1, @Nullable ResolvableType var2);
    }
    // 在AbstractApplicationcontext中有一个applicationEventMulticaster
    // 的成员变量,
    // 提供了监听器Listener的注册方法
    public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext, DisposableBean {private ApplicationEventMulticaster applicationEventMulticaster;protected void registerListeners() {// Register statically specified listeners first.for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let post-processors apply to them!String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);for (String lisName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(lisName);}}
    }

    事件机制工作流程

    监听器什么时候注册到IOC容器

    注册的开始逻辑是在AbstractApplicationContext类的refresh方法,该方法包含了整个IOC容器初始化所有方法。其中有一个registerListeners()方法就是注册系统监听者(Spring自带的)和自定义监听器的。

    public void refresh() throws BeansException, IllegalStateException {// BeanFactory准备工作完成后进行的后置处理工作this.postProcessBeanFactory(beanFactory);// 执行BeanFactoryPostProcessor的方法;this.invokeBeanFactoryPostProcessors(beanFactory);// 注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执行this.registerBeanPostProcessors(beanFactory);// 初始化MessageSource组件(做国际化功能;消息绑定,消息解析);this.initMessageSource();// 初始化事件派发器this.initApplicationEventMulticaster();// 子类重写这个方法,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器this.onRefresh();// 注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的this.registerListeners();// 初始化所有剩下的非懒加载的单例beanthis.finishBeanFactoryInitialization(beanFactory);// 完成context的刷新this.finishRefresh();}

    看registerListeners的关键方法体,其中的两个方法addApplicationListener和addApplicationListenerBean,从方法可以看出是添加监听者。

    protected void registerListeners() {Iterator var1 = this.getApplicationListeners().iterator();while(var1.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var1.next();this.getApplicationEventMulticaster().addApplicationListener(listener);}String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);String[] var7 = listenerBeanNames;int var3 = listenerBeanNames.length;for(int var4 = 0; var4 < var3; ++var4) {String listenerBeanName = var7[var4];this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);}
    }

    该接口主要两个职责,维护ApplicationListener相关类和发布事件。实现在默认实现类AbstractApplicationEventMulticaster,最后将Listener放到了内部类ListenerRetriever两个set集合中

    private class ListenerRetriever {public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet();public final Set<String> applicationListenerBeans = new LinkedHashSet();
    }

    ListenerRetriever被称为监听器注册表。

    Spring如何发布的事件并通知监听者

    这个注意的有两个方法

    publishEvent方法

    • AbstractApplicationContext实现了ApplicationEventPublisher 接口的publishEvent方法

     
    
    protected void publishEvent(Object event, @Nullable ResolvableType eventType) {Assert.notNull(event, "Event must not be null");Object applicationEvent;//尝试转换为ApplicationEvent或者PayloadApplicationEvent,如果是PayloadApplicationEvent则获取eventTypeif (event instanceof ApplicationEvent) {applicationEvent = (ApplicationEvent)event;} else {applicationEvent = new PayloadApplicationEvent(this, event);if (eventType == null) {eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();}}if (this.earlyApplicationEvents != null) {//判断earlyApplicationEvents是否为空(也就是早期事件还没有被发布-说明广播器还没有实例化好),如果不为空则将当前事件放入集合this.earlyApplicationEvents.add(applicationEvent);} else {//否则获取ApplicationEventMulticaster调用其multicastEvent将事件广播出去。本文这里获取到的广播器实例是SimpleApplicationEventMulticaster。this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);}//将事件交给父类处理if (this.parent != null) {if (this.parent instanceof AbstractApplicationContext) {((AbstractApplicationContext)this.parent).publishEvent(event, eventType);} else {this.parent.publishEvent(event);}}}

    multicastEvent方法继续进入到multicastEvent方法,该方法有两种方式调用invokeListener,通过线程池和直接调用,进一步说就是通过异步和同步两种方式调用.

    public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {//解析事件类型ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);//获取执行器Executor executor = this.getTaskExecutor();// 获取合适的ApplicationListener,循环调用监听器的onApplicationEvent方法Iterator var5 = this.getApplicationListeners(event, type).iterator();while(var5.hasNext()) {ApplicationListener<?> listener = (ApplicationListener)var5.next();if (executor != null) {//如果executor不为null,则交给executor去调用监听器executor.execute(() -> {this.invokeListener(listener, event);});} else {//否则,使用当前主线程直接调用监听器;this.invokeListener(listener, event);}}}

    invokeListener方法

    // 该方法增加了错误处理逻辑,然后调用doInvokeListener
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {ErrorHandler errorHandler = this.getErrorHandler();if (errorHandler != null) {try {this.doInvokeListener(listener, event);} catch (Throwable var5) {errorHandler.handleError(var5);}} else {this.doInvokeListener(listener, event);}}private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {//直接调用了listener接口的onApplicationEvent方法listener.onApplicationEvent(event);  
    }

    关键字:成人大专学校有哪些学校_抖音代运营服务内容_搜索引擎入口yandex_今日新闻头条官网

    版权声明:

    本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

    我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

    责任编辑: