99偷拍视频精品区一区二,口述久久久久久久久久久久,国产精品夫妇激情啪发布,成人永久免费网站在线观看,国产精品高清免费在线,青青草在线观看视频观看,久久久久久国产一区,天天婷婷久久18禁,日韩动漫av在线播放直播

4.7深入理解Spring-創新互聯

4.7.1 Spring 4.7.1.1?Spring模塊

Spring 由七大模塊組成,分別是

創新互聯專注于企業網絡營銷推廣、網站重做改版、谷城網站定制設計、自適應品牌網站建設、H5技術、購物商城網站建設、集團公司官網建設、外貿網站制作、高端網站制作、響應式網頁設計等建站業務,價格優惠性價比高,為谷城等各大城市提供網站開發制作服務。
  • 數據模塊(Data Access / Integration)
  • Web模塊
  • 切面模塊(Aop,Aspects)
  • 工具模塊(Instrumentation)
  • 消息模塊
  • 核心模塊
  • 測試模塊

Spring模塊

4.7.1.1.1?數據模塊

數據訪問與集成模塊,分為以下小模塊:

  • JDBC(Java Database Connectivity),Java數據庫連接
  • ORM(Object Relational Mapping),?對象關系映射
  • OXM(Object XML Mapping),?對象XML映射
  • JMS(Java Message Service),Java消息服務
  • Transactions,事務
4.7.1.1.2?Web模塊

Web有以下小模塊:

  • Web
  • WebMVC
  • WebSocket
  • WebFlux

Web 模塊:提供了核心部分,如 編解碼,過濾器,序列化,國際化,跨域,轉換器,客戶端和服務端等。

WebMVC 模塊:即我們平時用的?SpringMVC

WebSocket 模塊:?用來支持這個?全雙工通信

WebFlux模塊:?就是這個響應式Web編程模塊

4.7.1.1.3 切面模塊

包括AOP、Aspect兩個模塊。

AOP:基于代理的 Aop 框架

Aspect:定義了五種類型的切面

  • beans.factory.aspectj
  • cache.aspectj
  • context.annotation.aspectj
  • scheduling.aspectj
  • transaction.aspectj
4.7.1.1.4?工具模塊

Instrumentation , 這個是 Java 的一個接口,用于

  • 監控代理
  • 事件日志記錄
  • 代碼覆蓋率
4.7.1.1.5 消息模塊

Spring-messaging模塊提供了一種基于?WebSocket的?STOMP協議實現
STOMP(Simple Text Oriented Messaging Protocol) 是一種?流文本定向消息協議,也是一種為MOM(Message Oriented Middleware,面向消息的中間件)設計的簡單文本協議
常見的這幾個MQ都支持該協議,比如?RocketMQ,RabbitMQ,ActiveMQ。

待更新

Spring的這七大模塊你了解嗎? - 知乎

4.7.1.1.6 核心模塊

分為四個核心模塊:

  • Beans
  • Core
  • Context
  • Expression

該核心模塊為重點,

4.7.1.1.7 測試模塊

主要是測試用,如Junit等。


4.7.1.2?核心模塊?

4.7.2 SpringIOC架構原理
IOC流程圖
4.7.2.1 Bean初始化狀態

我們可以將bean概念態、定義態、純靜態、成熟態

概念態:

定義態:bean的構造圖

純靜態:循環依賴中體現純靜態的作用

成熟態:最終在應用中使用的bean

其中在ApplicationContext()中隱藏了另外兩種狀態

4.7.2.2 概念bean → 定義bean

BeanDefinition是相當重要的?

BeanDefinition:封裝了bean的定義信息,決定一個bean是怎么生產的,一個bean對應一個BeanDefinition

那么這個BeanDefinition是怎么來的呢?

當我們new ApplicationContext時會傳入一個xml文件。不同的sapring上下文會傳入不同的,讀取bean定義的過程是有些不同的,但也有相同的地方。

方式一:ClassPathXmlApplicationContext(xml);
方式二:AnnotationConfigApplicationContext(配置類);

無論是ClassPathXmlApplicationContext(xml)還是AnnotationConfigApplicationContext(配置類)都有一個統一的接口ApplicationContext,因此它們會將公共的部分抽取出來,我們來研究這些公共的部分。

雖然有不同的spring上下文,但是都是由BeanDefinitionReader接口讀取配置信息

讀取之后怎么解析注解呢?

用掃描器ClassPathBeanDefinitionScanner,比如,我們定義了

它會掃描包下的.class,里面有component注解,將這個類注冊為BeanDefinition。由于每個類都會有BenaDefinition,所以用beanDefinitionMap容器保存。

之后由registerBeanDefinition將BeanDefinition注冊到BeanDefinitionMap中

之后就是生產bean了。

4.7.2.3 生產bean

這里涉及到很重要的知識點:BeanFactory接口

BeanFactory負責生產,在BeanFactory中提供了getBean方法用來生產bean。

提出一個小問題,這里Spring容器調用的getBean和BeanFactory里的getBean是同一個方法嗎?

答案:是同一個

我們進入applicationContext.getBean(),會發現這里的getBean是門面方法,沒有具體,而是交給BeanFactory去生產。

當已存在bean就直接返回給spring,如果沒有就生產后返回。

既然ApplicationContext和BeanFactory都可以獲取bean,也就是說二者均可作為容器去使用。

那么既然都可以作為容器,為什么不直接在spring中書寫BeanFactroy,非要再整個ApplicationContext的門面方法,不多此一舉么?

看完上面的繼承圖,我們發現ApplicationContext實現了BeanFactroy,這就好比,我們要買車,我們可以選擇去4S店,也可以選擇直接去汽車工廠。ApplicationContext就好比4S店,4S店有很多的服務,我們只需要提需求,4S店都能完成。BeanFactroy就是汽車工廠,工廠的職責就一個:生產汽車?;旧衔覀兒?S店比較熟悉,打交道比較多,同樣我們開發人員和ApplicationContext打交道比較多。我們只需要把配置給ApplicationContext,它就能初始化。

但是BeanFactroy不行,它只實現了簡單工廠,功能單一化,只能根據BeanDefinition去生產bean。

通過ApplicationContext,我們只需要getBean(car),就可以得到我們想要的bean,但是,如果注釋了ApplicationContext,我們再直接用beanFactory.get(car),就會報錯BeanDefinitionException。

因為像xml、配置類的信息,都是由ApplicationContext(Spring 上下文)幫我們做了,ApplicationContext調用了BeanFactory來生產bean。

但是對于BeanFactory,我們必須手動將BenaDefinition傳給BeanFactory,才能生產bean。

但是BeanFactory內存更小,可以用于嵌入式開發。

4.7.2.4 實例化bean

實例化bean的方式:

  1. 反射
  2. 工廠方法
  3. 工廠類:FactoryBean
4.7.2.4.1 反射

@Component

將類讀取到beanClass中,spring利用反射實例化bean

4.7.2.4.2 工廠方法

注解形式

public class StaticFactoryBean {

?@Bean
? public static UserService createUserService(){ ? ?
????????? return new UserServiceImpl();
? }
}

會將被標注的方法讀取到factoryMethodName

xml形式

在factory-method=" "中指定一個工廠方法,且這個工廠方法是靜態的,會將方法讀取到factoryMethodName?

4.7.2.4.3 工廠類

注意FactoryBean本身也是一個bean

類實例化FactoryBean接口,并重寫getObject()、getObjectType()

@Component
public class FactoryBean_test implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
//這個才是返回的真正的bean
        return new User();
    }
 
    @Override
    public ClassgetObjectType() {
        return User.class;
    }

工廠方法基于方法,而工廠類基于類

4.7.2.5?屬性注入 4.7.2.5.1 循環依賴

4.7.2.6?初始化 4.7.2.6.1 初始化方法

屬性注入之后,進行初始化,初始化時會調用init_Method()

除了init-Method()外

還可以用注解@PostConstruct聲明一個初始化方法

以及利用InitializingBean接口,實現一個InitializingBean,重寫afterPropertiesSet()

4.7.2.6.2 aware擴展接口

檢查aware接口設置相關依賴

在spring容器中,我們可以把對象按照使用者分為兩類:自定義對象、容器使用的對象

  • 自定義對象:就是我們開發人員定義的Student、Taecher等對象
  • 容器使用的對象:BeanPostProcessor、BeanFactory等,這些都是由容器自己創建、自己調用。

但是如果我們自定義對象需要使用、調用這些容器所使用的對象時,怎么辦?

你可以把這些容器所使用的對象當成一個普通屬性,如果是屬性,我肯定要調用屬性的set方法,往里面賦值。但是,對象的創建都交由容器來管理了,set方法調用肯定還是由容器管理,而且容器又不知道什么時候調用。

所以這里設置了統一的入口——aware接口。

所有調用容器對象設置的地方都會實現aware接口,如BeanFactoryAware、BeanNameAware等。

總的來說就是通過aware的具體實現子類,我們可以設置bean的一系列操作。

4.7.2.7 創建Bean

創建好的bean會放入Map(單例池/一級緩存)中

當context.getBean("bean的名字");時,會到一級緩存中查詢,有就返回,沒有就生產。

4.7.2.8 擴展接口 4.7.2.8.1 BeanFactoryPostProcessor接口
@FunctionalInterface
public interface BeanFactoryPostProcessor {
    void postProcessBeanFactory(ConfigurableListableBeanFactory BeanFactory) throws BeansException;
}

BeanFactoryPostProcessor中的postProcessBeanFactory()方法,直接傳來一個

4.7.2.8.2 BeanDefinitionRegistryPostProcessor

源碼定義如下:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry var1) throws BeansException;
}

BeanDefinitionRegistryPostProcessor的作用是注冊BeanDefinition,也就是注冊了Bean

Spring-MyBatis中的Mapper是接口,動態代理

4.7.2.8.3 BeanPostProcessor

BeanPostProcessor(bean的后置處理器)主要用在初始化前后

BeanPostProcessor有很多子接口

4.7.3 Bean生命周期 4.7.3.1 簡化版本

1、實例化bean,當客戶向容器請求一個尚未初始化的bean時,容器就會調用doCreateBean()方法進行實例化,實際上就是利用反射來創建一個bean對象

2、當bean對象創建出來后就對bean對象進行屬性填充,也就是注入這個bean依賴的其他對象

3、屬性填充完成后,進行初始化bean操作

a、執行Aware接口方法,Spring會檢查該bean對象是否實現了xxxAware接口,通過Aware類型的接口,我們可以拿到spring容器的一些資源,如實現了BeanNameAware接口就可以獲取BeanName等等

b、執行BeanPostProcessor的前置處理方法postProcessBeforeInitialization(),對Bean進行一些自定義的前置處理

c、判斷bean是否實現了InitialalizationBean接口,如果實現了,將會執行InitialalizationBean的afterPropertiesSet()初始化方法

d、執行用戶自定義的初始化方法,如init-method等

e、執行BeanPostProcessor的后置處理方法postProcessAfterInitialization()

4、銷毀

a、首先判斷Bean是否實現了DestructionAwareBeanPostProcessor接口,如果實現了,則執行DestructionAwareBeanPostProcessor后置處理器的銷毀方法

b、其次判斷Bean是否實現了DisposableBean接口,如果實現了就會調用其實現的destroy()方法

c、最后判斷Bean是否配置了destroy-method方法,如果有就調用其配置的銷毀方法

4.7.3.2 詳細版本
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {

//bean
 protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }
//如果緩存中不存在,則調用createBeanInstance創建一個BeanWrapper(bean的包裝類)
        if (instanceWrapper == null) {
//bean的實例化
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
//初始化bean實例
 Object exposedObject = bean;

//----------------省略-----------
//屬性填充
            this.populateBean(beanName, mbd, instanceWrapper);
//初始化bean,如執行aware接口的子類,執行init-method方法,BeanPostProcesso后置增強等
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);


//銷毀不在AbstractAutowireCapableBeanFactory 類,在DisposableBeanAdapter類中


}

initializeBean

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() ->{
//先執行aware的子類
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

          Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
//執行beanPostProcessor后置處理器的前置方法BeanPostProcessorsBeforeInitialization
                wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
            }
//中間執行init-method
        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }
//最后執行BeanPostProcessorsAfterInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

invokeAwareMethods

private void invokeAwareMethods(String beanName, Object bean) {

        if (bean instanceof Aware) {
//如果bean實現了BeanNameAware,那bean內部可以獲取到beanName屬性
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }
//其他同理
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = this.getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                }
            }

            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

invokeInitMethods

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
//InitialalizationBean接口,如果實現了,將會執行InitialalizationBean的afterPropertiesSet()初始化方法
        boolean isInitializingBean = bean instanceof InitializingBean;
        if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }

            if (System.getSecurityManager() != null) {
                try {
//執行afterPropertiesSet()
                    AccessController.doPrivileged(() ->{
                        ((InitializingBean)bean).afterPropertiesSet();
                        return null;
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
                ((InitializingBean)bean).afterPropertiesSet();
            }
        }
//用戶自定義的初始化方法
        if (mbd != null && bean.getClass() != NullBean.class) {
            String initMethodName = mbd.getInitMethodName();
            if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
//用戶自定義的方法
                this.invokeCustomInitMethod(beanName, bean, mbd);
            }
        }

    }

DisposableBeanAdapter

//銷毀
class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
 public void destroy() {
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            Iterator var1 = this.beanPostProcessors.iterator();

            while(var1.hasNext()) {
//先查看DestructionAwareBeanPostProcessor接口
                DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();
//如果實現了,則執行DestructionAwareBeanPostProcessor后置處理器的銷毀方法
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }
//接著看是否實現了DisposableBean接口
              if (System.getSecurityManager() != null) {
                   AccessController.doPrivileged(() ->{
//如果實現了就調用接口的destroy方法
                       ((DisposableBean)this.bean).destroy();
                            
                }
              }
//最后判斷是否有用戶自定義的銷毀方法
           if (this.destroyMethod != null) {
            this.invokeCustomDestroyMethod(this.destroyMethod);
        } else if (this.destroyMethodName != null) {
            Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);
            if (methodToInvoke != null) {
//調用用戶自定義的銷毀方法
                this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
            }
        }
}

Spring的理解

Spring是什么?

框架:方便開發,整合其他框架

容器:管理bean

生態:目前主流的Java開發,都會用到Java全家桶。Springboot、Springcloud等框架都是對Spring的擴展實現。

11張流程圖搞定 Spring Bean 生命周期 - 知乎

4.7.3.3 循環依賴 4.7.3.3.1 循環依賴問題

4.7.3.3.2 解決方案:三級緩存

singletonObject(一級緩存):存放實例化 ->代理 ->屬性注入 ->初始化后的對象

earlySingletonObjects(二級緩存):存放實例化 ->代理 ->屬性注入 ->初始化后的對象

singletonFactories(三級緩存):存放對象工廠,可以從對象工廠中拿到還未屬性注入的對象(對象工廠便于創建代理對象)

4.7.3.3.3 流程

當getBean(),獲取bean時,spring會先到一級緩存中找,沒有再去二級緩存,若二級緩存還沒有就會創建一個對應的工廠對象

4.7.4 AOP

單例bean

Spring中的Bean對象默認是單例的,框架并沒有對Bean進行多線程封裝處理

單例bean是指IOC容器中就只有這么一個bean,是全局共享的。分為有狀態bean和無狀態bean。

有狀態的bean

就是有實例變量的對象,可以保存數據(有狀態就是有數據存儲功能),是線程不安全的。每個用戶都有自己特有的實例,在用戶的生命周期中,bean保存了用戶的信息,即為“偶狀態”;一旦用戶衰亡(調用結束),bean的生命周期也隨之結束。即每個用戶最初都會得到一個初始的bean。

無狀態的bean

就是沒有實例變量的對象,不能保存數據,是不變類,是線程安全的。bean一旦實例化就被加進會話池中,各個用戶都可以共用。即使用戶已經消亡,bean的生命期也不一定結束,它可能依然存在于會話池中,供其他用戶調用。由于沒有特定的用戶,那么也就不能保持某一用戶的狀態,所以叫無狀態bean。但無狀態會話bean 并非沒有狀態,如果它有自己的屬性(變量),那么這些變量就會受到所有調用它的用戶的影響,這是在實際應用中必須注意的。

實例變量

java類的成員變量有倆種:一種是被static關鍵字修飾的變量,叫類變量或者靜態變量;另一種沒有static修飾,為實例變量。

class Car{

private name;? ?//這就是實例變量

public void 方法(){};

}

當一個對象被實例化之后,每個實例變量的值就跟著確定;

實例變量在對象創建的時候創建,在對象被銷毀的時候銷毀;

如果Bean是有狀態的,那就需要開發人員自己來進行線程安全的保證,最簡單的辦法就是改變bean的作用域 把 "singleton"改為’‘protopyte’ 這樣每次請求Bean就相當于是 new Bean() 這樣就可以保證線程的安全了。

無狀態就是不會存儲數據,試想controller,service和dao本身并不是線程安全的,只是調用里面的方法,而且多線程調用一個實例的方法,會在內存中復制遍歷,這是自己線程的工作內存,是最安全的。因此在進行使用的時候,不要在bean中聲明任何有狀態的實例變量或者類變量,如果必須如此,也推薦大家使用ThreadLocal把變量變成線程私有,如果bean的實例變量或者類變量需要在多個線程之間共享,那么就只能使用synchronized、lock、cas等這些實現線程同步的方法。但是一旦使用了synchronized、lock等線程同步方法,又會降低系統效率。

你是否還在尋找穩定的海外服務器提供商?創新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統配攻擊溯源,準確流量調度確保服務器高可用性,企業級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

網頁題目:4.7深入理解Spring-創新互聯
地址分享:http://www.yijiale78.com/article16/doccgg.html

成都網站建設公司_創新互聯,為您提供App設計網站制作品牌網站建設、定制開發、外貿網站建設、營銷型網站建設

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網頁設計公司