欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

4.7深入理解Spring-創(chuàng)新互聯(lián)

4.7.1 Spring 4.7.1.1?Spring模塊

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

創(chuàng)新互聯(lián)專(zhuān)注于企業(yè)網(wǎng)絡(luò)營(yíng)銷(xiāo)推廣、網(wǎng)站重做改版、谷城網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5技術(shù)購(gòu)物商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為谷城等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
  • 數(shù)據(jù)模塊(Data Access / Integration)
  • Web模塊
  • 切面模塊(Aop,Aspects)
  • 工具模塊(Instrumentation)
  • 消息模塊
  • 核心模塊
  • 測(cè)試模塊

Spring模塊

4.7.1.1.1?數(shù)據(jù)模塊

數(shù)據(jù)訪問(wèn)與集成模塊,分為以下小模塊:

  • JDBC(Java Database Connectivity),Java數(shù)據(jù)庫(kù)連接
  • ORM(Object Relational Mapping),?對(duì)象關(guān)系映射
  • OXM(Object XML Mapping),?對(duì)象XML映射
  • JMS(Java Message Service),Java消息服務(wù)
  • Transactions,事務(wù)
4.7.1.1.2?Web模塊

Web有以下小模塊:

  • Web
  • WebMVC
  • WebSocket
  • WebFlux

Web 模塊:提供了核心部分,如 編解碼,過(guò)濾器,序列化,國(guó)際化,跨域,轉(zhuǎn)換器,客戶端和服務(wù)端等。

WebMVC 模塊:即我們平時(shí)用的?SpringMVC

WebSocket 模塊:?用來(lái)支持這個(gè)?全雙工通信

WebFlux模塊:?就是這個(gè)響應(yīng)式Web編程模塊

4.7.1.1.3 切面模塊

包括AOP、Aspect兩個(gè)模塊。

AOP:基于代理的 Aop 框架

Aspect:定義了五種類(lèi)型的切面

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

Instrumentation , 這個(gè)是 Java 的一個(gè)接口,用于

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

Spring-messaging模塊提供了一種基于?WebSocket的?STOMP協(xié)議實(shí)現(xiàn)
STOMP(Simple Text Oriented Messaging Protocol) 是一種?流文本定向消息協(xié)議,也是一種為MOM(Message Oriented Middleware,面向消息的中間件)設(shè)計(jì)的簡(jiǎn)單文本協(xié)議
常見(jiàn)的這幾個(gè)MQ都支持該協(xié)議,比如?RocketMQRabbitMQActiveMQ。

待更新

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

4.7.1.1.6 核心模塊

分為四個(gè)核心模塊:

  • Beans
  • Core
  • Context
  • Expression

該核心模塊為重點(diǎn),

4.7.1.1.7 測(cè)試模塊

主要是測(cè)試用,如Junit等。


4.7.1.2?核心模塊?

4.7.2 SpringIOC架構(gòu)原理
IOC流程圖
4.7.2.1 Bean初始化狀態(tài)

我們可以將bean概念態(tài)、定義態(tài)、純靜態(tài)、成熟態(tài)

概念態(tài):

定義態(tài):bean的構(gòu)造圖

純靜態(tài):循環(huán)依賴中體現(xiàn)純靜態(tài)的作用

成熟態(tài):最終在應(yīng)用中使用的bean

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

4.7.2.2 概念bean → 定義bean

BeanDefinition是相當(dāng)重要的?

BeanDefinition:封裝了bean的定義信息,決定一個(gè)bean是怎么生產(chǎn)的,一個(gè)bean對(duì)應(yīng)一個(gè)BeanDefinition

那么這個(gè)BeanDefinition是怎么來(lái)的呢?

當(dāng)我們new ApplicationContext時(shí)會(huì)傳入一個(gè)xml文件。不同的sapring上下文會(huì)傳入不同的,讀取bean定義的過(guò)程是有些不同的,但也有相同的地方。

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

無(wú)論是ClassPathXmlApplicationContext(xml)還是AnnotationConfigApplicationContext(配置類(lèi))都有一個(gè)統(tǒng)一的接口ApplicationContext,因此它們會(huì)將公共的部分抽取出來(lái),我們來(lái)研究這些公共的部分。

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

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

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

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

之后由registerBeanDefinition將BeanDefinition注冊(cè)到BeanDefinitionMap中

之后就是生產(chǎn)bean了。

4.7.2.3 生產(chǎn)bean

這里涉及到很重要的知識(shí)點(diǎn):BeanFactory接口

BeanFactory負(fù)責(zé)生產(chǎn),在BeanFactory中提供了getBean方法用來(lái)生產(chǎn)bean。

提出一個(gè)小問(wèn)題,這里Spring容器調(diào)用的getBean和BeanFactory里的getBean是同一個(gè)方法嗎?

答案:是同一個(gè)

我們進(jìn)入applicationContext.getBean(),會(huì)發(fā)現(xiàn)這里的getBean是門(mén)面方法,沒(méi)有具體,而是交給BeanFactory去生產(chǎn)。

當(dāng)已存在bean就直接返回給spring,如果沒(méi)有就生產(chǎn)后返回。

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

那么既然都可以作為容器,為什么不直接在spring中書(shū)寫(xiě)B(tài)eanFactroy,非要再整個(gè)ApplicationContext的門(mén)面方法,不多此一舉么?

看完上面的繼承圖,我們發(fā)現(xiàn)ApplicationContext實(shí)現(xiàn)了BeanFactroy,這就好比,我們要買(mǎi)車(chē),我們可以選擇去4S店,也可以選擇直接去汽車(chē)工廠。ApplicationContext就好比4S店,4S店有很多的服務(wù),我們只需要提需求,4S店都能完成。BeanFactroy就是汽車(chē)工廠,工廠的職責(zé)就一個(gè):生產(chǎn)汽車(chē)。基本上我們和4S店比較熟悉,打交道比較多,同樣我們開(kāi)發(fā)人員和ApplicationContext打交道比較多。我們只需要把配置給ApplicationContext,它就能初始化。

但是BeanFactroy不行,它只實(shí)現(xiàn)了簡(jiǎn)單工廠,功能單一化,只能根據(jù)BeanDefinition去生產(chǎn)bean。

通過(guò)ApplicationContext,我們只需要getBean(car),就可以得到我們想要的bean,但是,如果注釋了ApplicationContext,我們?cè)僦苯佑胋eanFactory.get(car),就會(huì)報(bào)錯(cuò)BeanDefinitionException。

因?yàn)橄駒ml、配置類(lèi)的信息,都是由ApplicationContext(Spring 上下文)幫我們做了,ApplicationContext調(diào)用了BeanFactory來(lái)生產(chǎn)bean。

但是對(duì)于BeanFactory,我們必須手動(dòng)將BenaDefinition傳給BeanFactory,才能生產(chǎn)bean。

但是BeanFactory內(nèi)存更小,可以用于嵌入式開(kāi)發(fā)。

4.7.2.4 實(shí)例化bean

實(shí)例化bean的方式:

  1. 反射
  2. 工廠方法
  3. 工廠類(lèi):FactoryBean
4.7.2.4.1 反射

@Component

將類(lèi)讀取到beanClass中,spring利用反射實(shí)例化bean

4.7.2.4.2 工廠方法

注解形式

public class StaticFactoryBean {

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

會(huì)將被標(biāo)注的方法讀取到factoryMethodName

xml形式

在factory-method=" "中指定一個(gè)工廠方法,且這個(gè)工廠方法是靜態(tài)的,會(huì)將方法讀取到factoryMethodName?

4.7.2.4.3 工廠類(lèi)

注意FactoryBean本身也是一個(gè)bean

類(lèi)實(shí)例化FactoryBean接口,并重寫(xiě)getObject()、getObjectType()

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

工廠方法基于方法,而工廠類(lèi)基于類(lèi)

4.7.2.5?屬性注入 4.7.2.5.1 循環(huán)依賴

4.7.2.6?初始化 4.7.2.6.1 初始化方法

屬性注入之后,進(jìn)行初始化,初始化時(shí)會(huì)調(diào)用init_Method()

除了init-Method()外

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

以及利用InitializingBean接口,實(shí)現(xiàn)一個(gè)InitializingBean,重寫(xiě)afterPropertiesSet()

4.7.2.6.2 aware擴(kuò)展接口

檢查aware接口設(shè)置相關(guān)依賴

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

  • 自定義對(duì)象:就是我們開(kāi)發(fā)人員定義的Student、Taecher等對(duì)象
  • 容器使用的對(duì)象:BeanPostProcessor、BeanFactory等,這些都是由容器自己創(chuàng)建、自己調(diào)用。

但是如果我們自定義對(duì)象需要使用、調(diào)用這些容器所使用的對(duì)象時(shí),怎么辦?

你可以把這些容器所使用的對(duì)象當(dāng)成一個(gè)普通屬性,如果是屬性,我肯定要調(diào)用屬性的set方法,往里面賦值。但是,對(duì)象的創(chuàng)建都交由容器來(lái)管理了,set方法調(diào)用肯定還是由容器管理,而且容器又不知道什么時(shí)候調(diào)用。

所以這里設(shè)置了統(tǒng)一的入口——aware接口。

所有調(diào)用容器對(duì)象設(shè)置的地方都會(huì)實(shí)現(xiàn)aware接口,如BeanFactoryAware、BeanNameAware等。

總的來(lái)說(shuō)就是通過(guò)aware的具體實(shí)現(xiàn)子類(lèi),我們可以設(shè)置bean的一系列操作。

4.7.2.7 創(chuàng)建Bean

創(chuàng)建好的bean會(huì)放入Map(單例池/一級(jí)緩存)中

當(dāng)context.getBean("bean的名字");時(shí),會(huì)到一級(jí)緩存中查詢,有就返回,沒(méi)有就生產(chǎn)。

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

BeanFactoryPostProcessor中的postProcessBeanFactory()方法,直接傳來(lái)一個(gè)

4.7.2.8.2 BeanDefinitionRegistryPostProcessor

源碼定義如下:

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

BeanDefinitionRegistryPostProcessor的作用是注冊(cè)BeanDefinition,也就是注冊(cè)了Bean

Spring-MyBatis中的Mapper是接口,動(dòng)態(tài)代理

4.7.2.8.3 BeanPostProcessor

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

BeanPostProcessor有很多子接口

4.7.3 Bean生命周期 4.7.3.1 簡(jiǎn)化版本

1、實(shí)例化bean,當(dāng)客戶向容器請(qǐng)求一個(gè)尚未初始化的bean時(shí),容器就會(huì)調(diào)用doCreateBean()方法進(jìn)行實(shí)例化,實(shí)際上就是利用反射來(lái)創(chuàng)建一個(gè)bean對(duì)象

2、當(dāng)bean對(duì)象創(chuàng)建出來(lái)后就對(duì)bean對(duì)象進(jìn)行屬性填充,也就是注入這個(gè)bean依賴的其他對(duì)象

3、屬性填充完成后,進(jìn)行初始化bean操作

a、執(zhí)行Aware接口方法,Spring會(huì)檢查該bean對(duì)象是否實(shí)現(xiàn)了xxxAware接口,通過(guò)Aware類(lèi)型的接口,我們可以拿到spring容器的一些資源,如實(shí)現(xiàn)了BeanNameAware接口就可以獲取BeanName等等

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

c、判斷bean是否實(shí)現(xiàn)了InitialalizationBean接口,如果實(shí)現(xiàn)了,將會(huì)執(zhí)行InitialalizationBean的afterPropertiesSet()初始化方法

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

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

4、銷(xiāo)毀

a、首先判斷Bean是否實(shí)現(xiàn)了DestructionAwareBeanPostProcessor接口,如果實(shí)現(xiàn)了,則執(zhí)行DestructionAwareBeanPostProcessor后置處理器的銷(xiāo)毀方法

b、其次判斷Bean是否實(shí)現(xiàn)了DisposableBean接口,如果實(shí)現(xiàn)了就會(huì)調(diào)用其實(shí)現(xiàn)的destroy()方法

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

4.7.3.2 詳細(xì)版本
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);
        }
//如果緩存中不存在,則調(diào)用createBeanInstance創(chuàng)建一個(gè)BeanWrapper(bean的包裝類(lèi))
        if (instanceWrapper == null) {
//bean的實(shí)例化
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }
//初始化bean實(shí)例
 Object exposedObject = bean;

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


//銷(xiāo)毀不在AbstractAutowireCapableBeanFactory 類(lèi),在DisposableBeanAdapter類(lèi)中


}

initializeBean

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

          Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
//執(zhí)行beanPostProcessor后置處理器的前置方法BeanPostProcessorsBeforeInitialization
                wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
            }
//中間執(zhí)行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);
        }
//最后執(zhí)行BeanPostProcessorsAfterInitialization
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

invokeAwareMethods

private void invokeAwareMethods(String beanName, Object bean) {

        if (bean instanceof Aware) {
//如果bean實(shí)現(xiàn)了BeanNameAware,那bean內(nèi)部可以獲取到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接口,如果實(shí)現(xiàn)了,將會(huì)執(zhí)行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 {
//執(zhí)行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

//銷(xiāo)毀
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();
//如果實(shí)現(xiàn)了,則執(zhí)行DestructionAwareBeanPostProcessor后置處理器的銷(xiāo)毀方法
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }
//接著看是否實(shí)現(xiàn)了DisposableBean接口
              if (System.getSecurityManager() != null) {
                   AccessController.doPrivileged(() ->{
//如果實(shí)現(xiàn)了就調(diào)用接口的destroy方法
                       ((DisposableBean)this.bean).destroy();
                            
                }
              }
//最后判斷是否有用戶自定義的銷(xiāo)毀方法
           if (this.destroyMethod != null) {
            this.invokeCustomDestroyMethod(this.destroyMethod);
        } else if (this.destroyMethodName != null) {
            Method methodToInvoke = this.determineDestroyMethod(this.destroyMethodName);
            if (methodToInvoke != null) {
//調(diào)用用戶自定義的銷(xiāo)毀方法
                this.invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
            }
        }
}

Spring的理解

Spring是什么?

框架:方便開(kāi)發(fā),整合其他框架

容器:管理bean

生態(tài):目前主流的Java開(kāi)發(fā),都會(huì)用到Java全家桶。Springboot、Springcloud等框架都是對(duì)Spring的擴(kuò)展實(shí)現(xiàn)。

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

4.7.3.3 循環(huán)依賴 4.7.3.3.1 循環(huán)依賴問(wèn)題

4.7.3.3.2 解決方案:三級(jí)緩存

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

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

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

4.7.3.3.3 流程

當(dāng)getBean(),獲取bean時(shí),spring會(huì)先到一級(jí)緩存中找,沒(méi)有再去二級(jí)緩存,若二級(jí)緩存還沒(méi)有就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的工廠對(duì)象

4.7.4 AOP

單例bean

Spring中的Bean對(duì)象默認(rèn)是單例的,框架并沒(méi)有對(duì)Bean進(jìn)行多線程封裝處理

單例bean是指IOC容器中就只有這么一個(gè)bean,是全局共享的。分為有狀態(tài)bean和無(wú)狀態(tài)bean。

有狀態(tài)的bean

就是有實(shí)例變量的對(duì)象,可以保存數(shù)據(jù)(有狀態(tài)就是有數(shù)據(jù)存儲(chǔ)功能),是線程不安全的。每個(gè)用戶都有自己特有的實(shí)例,在用戶的生命周期中,bean保存了用戶的信息,即為“偶狀態(tài)”;一旦用戶衰亡(調(diào)用結(jié)束),bean的生命周期也隨之結(jié)束。即每個(gè)用戶最初都會(huì)得到一個(gè)初始的bean。

無(wú)狀態(tài)的bean

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

實(shí)例變量

java類(lèi)的成員變量有倆種:一種是被static關(guān)鍵字修飾的變量,叫類(lèi)變量或者靜態(tài)變量;另一種沒(méi)有static修飾,為實(shí)例變量。

class Car{

private name;? ?//這就是實(shí)例變量

public void 方法(){};

}

當(dāng)一個(gè)對(duì)象被實(shí)例化之后,每個(gè)實(shí)例變量的值就跟著確定;

實(shí)例變量在對(duì)象創(chuàng)建的時(shí)候創(chuàng)建,在對(duì)象被銷(xiāo)毀的時(shí)候銷(xiāo)毀;

如果Bean是有狀態(tài)的,那就需要開(kāi)發(fā)人員自己來(lái)進(jìn)行線程安全的保證,最簡(jiǎn)單的辦法就是改變bean的作用域 把 "singleton"改為’‘protopyte’ 這樣每次請(qǐng)求Bean就相當(dāng)于是 new Bean() 這樣就可以保證線程的安全了。

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

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁(yè)題目:4.7深入理解Spring-創(chuàng)新互聯(lián)
地址分享:http://www.chinadenli.net/article16/doccgg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)網(wǎng)站制作品牌網(wǎng)站建設(shè)定制開(kāi)發(fā)外貿(mào)網(wǎng)站建設(shè)營(yíng)銷(xiāo)型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)頁(yè)設(shè)計(jì)公司