Spring service本類中方法調(diào)用另一個方法事務不生效問題

轉(zhuǎn)自CSDN 原文鏈接

前些日子一朋友在需要在目標對象中進行自我調(diào)用,且需要實施相應的事務定義霎肯,且網(wǎng)上的一種通過BeanPostProcessor的解決方案是存在問題的。因此專門寫此篇帖子分析why榛斯。

1观游、預備知識

aop概念請參考【http://www.iteye.com/topic/1122401】和【http://jinnianshilongnian.iteye.com/blog/1418596

spring的事務管理,請參考【http://jinnianshilongnian.iteye.com/blog/1441271

使用AOP 代理后的方法調(diào)用執(zhí)行流程驮俗,如圖所示


a7d8d493-e387-34e9-a637-8a4d8d438602.jpg

也就是說我們首先調(diào)用的是AOP代理對象而不是目標對象懂缕,首先執(zhí)行事務切面,事務切面內(nèi)部通過TransactionInterceptor環(huán)繞增強進行事務的增強王凑,即進入目標方法之前開啟事務搪柑,退出目標方法時提交/回滾事務。

2索烹、測試代碼準備

Java代碼

 public interface AService {  
    public void a();  
    public void b();  
}  
   
@Service()  
public class AServiceImpl1 implements AService{  
    @Transactional(propagation = Propagation.REQUIRED)  
    public void a() {  
        this.b();  
    }  
    @Transactional(propagation = Propagation.REQUIRES_NEW)  
    public void b() {  
    }  
}  

3工碾、問題

目標對象內(nèi)部的自我調(diào)用將無法實施切面中的增強,如圖所示

d33ee177-cf3f-39cc-befe-533306b0715f.jpg

此處的this指向目標對象百姓,因此調(diào)用this.b()將不會執(zhí)行b事務切面渊额,即不會執(zhí)行事務增強,因此b方法的事務定義“@Transactional(propagation = Propagation.REQUIRES_NEW)”將不會實施瓣戚,即結(jié)果是b和a方法的事務定義是一樣的端圈,可以從以下日志看出:

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource Adding transactional method 'a' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
org.springframework.beans.factory.support.DefaultListableBeanFactory Returning cached instance of singleton bean 'txManager'
org.springframework.orm.hibernate4.HibernateTransactionManager Creating new transaction with name [com.sishuok.service.impl.AServiceImpl1.a]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' -----創(chuàng)建a方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session …… for Hibernate transaction ---打開Session
……
org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization
org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl1.a]
org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl1.a] ----完成a方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit

org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session ……---提交a方法事務

org.springframework.orm.hibernate4.HibernateTransactionManager Rolling back Hibernate transaction on Session ……---如果有異常將回滾a方法事務

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization
org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization
……
org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction --關閉Session

我們可以看到事務切面只對a方法進行了事務增強焦读,沒有對b方法進行增強子库。

3、解決方案

此處a方法中調(diào)用b方法時矗晃,只要通過AOP代理調(diào)用b方法即可走事務切面仑嗅,即可以進行事務增強,如下所示:

Java代碼

public void a() {  
    aopProxy.b();//即調(diào)用AOP代理對象的b方法即可執(zhí)行事務切面進行事務增強  
}  

判斷一個Bean是否是AOP代理對象可以使用如下三種方法:
AopUtils.isAopProxy(bean) : 是否是代理對象;
AopUtils.isCglibProxy(bean) : 是否是CGLIB方式的代理對象仓技;
AopUtils.isJdkDynamicProxy(bean) : 是否是JDK動態(tài)代理方式的代理對象鸵贬;

3.1、通過ThreadLocal暴露Aop代理對象

1脖捻、開啟暴露Aop代理到ThreadLocal支持(如下配置方式從spring3開始支持)

  <aop:aspectj-autoproxy expose-proxy="true"/><!—注解風格支持-->
  <aop:config expose-proxy="true"><!—xml風格支持-->

2阔逼、修改我們的業(yè)務實現(xiàn)類

  this.b();-----------修改為--------->((AService) AopContext.currentProxy()).b();

3、執(zhí)行測試用例地沮,日志如下

org.springframework.beans.factory.support.DefaultListableBeanFactory Returning cached instance of singleton bean 'txManager'
org.springframework.orm.hibernate4.HibernateTransactionManager Creating new transaction with name [com.sishuok.service.impl.AServiceImpl2.a]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; '' -----創(chuàng)建a方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session ……for Hibernate transaction --打開a Session
org.springframework.orm.hibernate4.HibernateTransactionManager Preparing JDBC Connection of Hibernate Session ……
org.springframework.orm.hibernate4.HibernateTransactionManager Exposing Hibernate transaction as JDBC transaction ……
……
org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization
org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl2.a]

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource Adding transactional method 'b' with attribute: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; ''
……
org.springframework.orm.hibernate4.HibernateTransactionManager Suspending current transaction, creating new transaction with name [com.sishuok.service.impl.AServiceImpl2.b] -----創(chuàng)建b方法事務(并暫停a方法事務)
……
org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session for Hibernate transaction ---打開b Session
……
org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization
org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl2.b]
org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl2.b] ----完成b方法事務

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit
org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session …… ---提交b方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization
org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization
……
org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction --關閉 b Session

-----到此b方法事務完畢

org.springframework.orm.hibernate4.HibernateTransactionManager Resuming suspended transaction after completion of inner transaction ---恢復a方法事務
……
org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization
org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl2.a] ----完成a方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit
org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session ……---提交a方法事務
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization
org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization
org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization
……
org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction --關閉 a Session

此處我們可以看到b方法的事務起作用了嗜浮。

以上方式是解決目標對象內(nèi)部方法自我調(diào)用并實施事務的最簡單的解決方案。

4摩疑、實現(xiàn)原理分析

11bcfc1c-06cd-3443-a3c6-944320476689.jpg
  • 4.1危融、在進入代理對象之后通過AopContext.serCurrentProxy(proxy)暴露當前代理對象到ThreadLocal,并保存上次ThreadLocal綁定的代理對象為oldProxy雷袋;

  • 4.2吉殃、接下來我們可以通過 AopContext.currentProxy() 獲取當前代理對象;

  • 4.3楷怒、在退出代理對象之前要重新將ThreadLocal綁定的代理對象設置為上一次的代理對象蛋勺,即AopContext.serCurrentProxy(oldProxy)。

有些人不喜歡這種方式鸠删,說通過ThreadLocal暴露有性能問題迫卢,其實這個不需要考慮,因為事務相關的(Session和Connection)內(nèi)部也是通過SessionHolder和ConnectionHolder暴露到ThreadLocal實現(xiàn)的冶共。

不過自我調(diào)用這種場景確實只有很少情況遇到乾蛤,因此不用這種方式我們也可以通過如下方式實現(xiàn)。

3.2捅僵、通過初始化方法在目標對象中注入代理對象

Java代碼

@Service  
public class AServiceImpl3 implements AService{  
    @Autowired  //①  注入上下文  
    private ApplicationContext context;  
      
    private AService proxySelf; //②  表示代理對象家卖,不是目標對象  
    @PostConstruct  //③ 初始化方法  
    private void setSelf() {  
        //從上下文獲取代理對象(如果通過proxtSelf=this是不對的,this是目標對象)  
        //此種方法不適合于prototype Bean庙楚,因為每次getBean返回一個新的Bean  
        proxySelf = context.getBean(AService.class);   
    }  
    @Transactional(propagation = Propagation.REQUIRED)  
    public void a() {  
       proxySelf.b(); //④ 調(diào)用代理對象的方法 這樣可以執(zhí)行事務切面  
    }  
    @Transactional(propagation = Propagation.REQUIRES_NEW)  
    public void b() {  
    }  
}  

此處日志就不分析上荡,和3.1類似。此種方式不是很靈活馒闷,所有需要自我調(diào)用的實現(xiàn)類必須重復實現(xiàn)代碼酪捡。

3.3、通過BeanPostProcessor在目標對象中注入代理對象

此種解決方案可以參考http://fyting.iteye.com/blog/109236纳账。

BeanPostProcessor 的介紹和使用敬請等待我的下一篇分析帖逛薇。

一、定義BeanPostProcessor 需要使用的標識接口

Java代碼

public interface BeanSelfAware {  
    void setSelf(Object proxyBean);  
}  

即我們自定義的BeanPostProcessor (InjectBeanSelfProcessor)如果發(fā)現(xiàn)我們的Bean是實現(xiàn)了該標識接口就調(diào)用setSelf注入代理對象疏虫。

二永罚、Bean實現(xiàn)

Java代碼

@Service  
public class AServiceImpl4 implements AService, BeanSelfAware {//此處省略接口定義  
    private AService proxySelf;  
    public void setSelf(Object proxyBean) { //通過InjectBeanSelfProcessor注入自己(目標對象)的AOP代理對象  
        this.proxySelf = (AService) proxyBean;  
    }  
    @Transactional(propagation = Propagation.REQUIRED)  
    public void a() {  
        proxySelf.b();//調(diào)用代理對象的方法 這樣可以執(zhí)行事務切面  
    }  
    @Transactional(propagation = Propagation.REQUIRES_NEW)  
    public void b() {  
    }  
}   

實現(xiàn)BeanSelfAware標識接口的setSelf將代理對象注入啤呼,并且通過“proxySelf.b()”這樣可以實施b方法的事務定義。

三呢袱、InjectBeanSelfProcessor實現(xiàn)

Java代碼

@Component  
public class InjectBeanSelfProcessor implements BeanPostProcessor {  
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
        return bean;  
    }  
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
        if(bean instanceof BeanSelfAware) {//如果Bean實現(xiàn)了BeanSelfAware標識接口官扣,就將代理對象注入  
            ((BeanSelfAware) bean).setSelf(bean); //即使是prototype Bean也可以使用此種方式  
        }  
        return bean;  
    }  
}  

postProcessAfterInitialization根據(jù)目標對象是否實現(xiàn)BeanSelfAware標識接口,通過setSelf(bean)將代理對象(bean)注入到目標對象中羞福,從而可以完成目標對象內(nèi)部的自我調(diào)用惕蹄。

關于BeanPostProcessor的執(zhí)行流程等請一定參考我的這篇帖子,否則無法繼續(xù)往下執(zhí)行治专。

四焊唬、InjectBeanSelfProcessor的問題

(1、場景:通過InjectBeanSelfProcessor進行注入代理對象且循環(huán)依賴場景下會產(chǎn)生前者無法通過setSelf設置代理對象的問題看靠。 循環(huán)依賴是應該避免的赶促,但是實際工作中不可避免會有人使用這種注入,畢竟沒有強制性挟炬。

(2鸥滨、用例

(2.1、定義BeanPostProcessor 需要使用的標識接口

和3.1中一樣此處不再重復谤祖。

(2.2婿滓、Bean實現(xiàn)

Java代碼

@Service  
public class AServiceImpl implements AService, BeanSelfAware {//此處省略Aservice接口定義  
    @Autowired  
    private BService bService;   //①  通過@Autowired方式注入BService  
    private AService self;       //②  注入自己的AOP代理對象  
    public void setSelf(Object proxyBean) {  
        this.self = (AService) proxyBean;  //③ 通過InjectBeanSelfProcessor注入自己(目標對象)的AOP代理對象  
        System.out.println("AService=="+ AopUtils.isAopProxy(this.self)); //如果輸出true標識AOP代理對象注入成功  
    }  
    @Transactional(propagation = Propagation.REQUIRED)  
    public void a() {  
        self.b();  
    }  
    @Transactional(propagation = Propagation.REQUIRES_NEW)  
    public void b() {  
    }  
}  

Java代碼

@Service  
public class BServiceImpl implements BService, BeanSelfAware {//此處省略Aservice接口定義  
    @Autowired  
    private AService aService;  //①  通過@Autowired方式注入AService  
    private BService self;      //②  注入自己的AOP代理對象  
    public void setSelf(Object proxyBean) {  //③ 通過InjectBeanSelfProcessor注入自己(目標對象)的AOP代理對象  
        this.self = (BService) proxyBean;  
        System.out.println("BService=" + AopUtils.isAopProxy(this.self)); //如果輸出true標識AOP代理對象注入成功  
    }  
    @Transactional(propagation = Propagation.REQUIRED)  
    public void a() {  
        self.b();  
    }  
    @Transactional(propagation = Propagation.REQUIRES_NEW)  
    public void b() {  
    }  
}  

此處A依賴B,B依賴A粥喜,即構(gòu)成循環(huán)依賴凸主,此處不探討循環(huán)依賴的設計問題(實際工作應該避免循環(huán)依賴),只探討為什么循環(huán)依賴會出現(xiàn)注入代理對象失敗的問題额湘。

循環(huán)依賴請參考我的博文http://jinnianshilongnian.iteye.com/blog/1415278卿吐。

依賴的初始化和銷毀順序請參考我的博文http://jinnianshilongnian.iteye.com/blog/1415461

(2.3锋华、InjectBeanSelfProcessor實現(xiàn)

和之前3.3中一樣 此處不再重復嗡官。

(2.4、測試用例

Java代碼

@RunWith(value = SpringJUnit4ClassRunner.class)  
@ContextConfiguration(value = {"classpath:spring-config.xml"})  
public class SelfInjectTest {  
    @Autowired  
    AService aService;  
    @Autowired  
    BService bService;  
    @Test  
    public void test() {  
    }  
}  

執(zhí)行如上測試用例會輸出:

BService=true

AService==false

即BService通過InjectBeanSelfProcessor注入代理對象成功毯焕,而AService卻失敗了(實際是注入了目標對象)衍腥,如下是debug得到的信息:

abcbe77b-491a-3e3a-97fd-a560d01a886b.jpg
ff7eef80-207b-31ed-8fa8-08990fec1e82.jpg

(2. 5、這是為什么呢纳猫,怎么在循環(huán)依賴會出現(xiàn)這種情況婆咸?

敬請期待我的下一篇分析帖。

3.4芜辕、改進版的InjectBeanSelfProcessor的解決方案

Java代碼

@Component  
public class InjectBeanSelfProcessor2 implements BeanPostProcessor, ApplicationContextAware {  
    private ApplicationContext context;  
    //① 注入ApplicationContext  
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
        this.context = applicationContext;  
    }  
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {  
        if(!(bean instanceof BeanSelfAware)) { //② 如果Bean沒有實現(xiàn)BeanSelfAware標識接口 跳過  
            return bean;  
        }  
        if(AopUtils.isAopProxy(bean)) { //③ 如果當前對象是AOP代理對象尚骄,直接注入  
            ((BeanSelfAware) bean).setSelf(bean);  
        } else {  
            //④ 如果當前對象不是AOP代理,則通過context.getBean(beanName)獲取代理對象并注入  
            //此種方式不適合解決prototype Bean的代理對象注入  
            ((BeanSelfAware)bean).setSelf(context.getBean(beanName));  
        }  
        return bean;  
    }  
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {  
        return bean;  
    }  
}  

5物遇、總結(jié)

縱觀其上:
【3.1 通過ThreadLocal暴露Aop代理對象】適合解決所有場景(不管是singleton Bean還是prototype Bean)的AOP代理獲取問題(即能解決目標對象的自我調(diào)用問題)乖仇;

【3.2 通過初始化方法在目標對象中注入代理對象】 和【3.4 改進版的InjectBeanSelfProcessor的解決方案】能解決普通(無循環(huán)依賴)的AOP代理對象注入問題憾儒,而且也能解決【3.3】中提到的循環(huán)依賴(應該是singleton之間的循環(huán)依賴)造成的目標對象無法注入AOP代理對象問題询兴,但該解決方案不適合解決循環(huán)依賴中包含prototype Bean的自我調(diào)用問題乃沙;

【3.3 通過BeanPostProcessor 在目標對象中注入代理對象】:只能解決 普通(無循環(huán)依賴)的 的Bean注入AOP代理,無法解決循環(huán)依賴的AOP代理對象注入問題诗舰,即無法解決目標對象的自我調(diào)用問題警儒。

jingnianshilongnian 寫道

spring允許的循環(huán)依賴(只考慮單例和原型Bean):
A----B
B----A
只有在A和B都不為原型是允許的,即如果A和B都是prototype則會報錯(無法進行原型Bean的循環(huán)依賴)眶根。
A(單例)---B(單例) 或 A(原型)---B(單例) 這是可以的蜀铲,但 A(原型)---B(原型)或 A(原型)---B(單例Lazy)【且context.getBean("A")】時 這是不允許的。

一属百、A(原型)---B(原型) A(原型)---B(單例Lazy)【且context.getBean("A")】 會報:
Error creating bean with name 'BServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sishuok.issue.AService com.sishuok.issue.impl.BServiceImpl.aService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'AServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.sishuok.issue.BService com.sishuok.issue.impl.AServiceImpl.bService; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'BServiceImpl': Requested bean is currently in creation: [color=red]Is there an unresolvable circular reference[/color]?

二记劝、A(原型)---B(單例) 和 A(單例)---B(單例)
這種方式 使用我的 【3.3 通過BeanPostProcessor 在目標對象中注入代理對象】 是沒有問題的。

因此【 3.4 改進版的InjectBeanSelfProcessor的解決方案 】 可以作為最后的解決方案族扰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末厌丑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子渔呵,更是在濱河造成了極大的恐慌怒竿,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扩氢,死亡現(xiàn)場離奇詭異耕驰,居然都是意外死亡,警方通過查閱死者的電腦和手機录豺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門朦肘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人双饥,你說我怎么就攤上這事厚骗。” “怎么了兢哭?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵领舰,是天一觀的道長。 經(jīng)常有香客問我迟螺,道長冲秽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任矩父,我火速辦了婚禮锉桑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘窍株。我一直安慰自己民轴,他們只是感情好攻柠,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著后裸,像睡著了一般瑰钮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上微驶,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天浪谴,我揣著相機與錄音,去河邊找鬼因苹。 笑死苟耻,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的扶檐。 我是一名探鬼主播凶杖,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼款筑!你這毒婦竟也來了智蝠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤醋虏,失蹤者是張志新(化名)和其女友劉穎寻咒,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颈嚼,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡毛秘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阻课。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片叫挟。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖限煞,靈堂內(nèi)的尸體忽然破棺而出抹恳,到底是詐尸還是另有隱情,我是刑警寧澤署驻,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布奋献,位于F島的核電站,受9級特大地震影響旺上,放射性物質(zhì)發(fā)生泄漏瓶蚂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一宣吱、第九天 我趴在偏房一處隱蔽的房頂上張望窃这。 院中可真熱鬧,春花似錦征候、人聲如沸杭攻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兆解。三九已至馆铁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痪宰,已是汗流浹背叼架。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工畔裕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留衣撬,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓扮饶,卻偏偏與公主長得像具练,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子甜无,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理扛点,服務發(fā)現(xiàn),斷路器岂丘,智...
    卡卡羅2017閱讀 134,716評論 18 139
  • 1. Java基礎部分 基礎部分的順序:基本語法陵究,類相關的語法,內(nèi)部類的語法奥帘,繼承相關的語法铜邮,異常的語法,線程的語...
    子非魚_t_閱讀 31,665評論 18 399
  • 這部分主要是開源Java EE框架方面的內(nèi)容寨蹋,包括Hibernate松蒜、MyBatis、Spring已旧、Spring ...
    雜貨鋪老板閱讀 1,397評論 0 2
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,867評論 6 342
  • 什么是Spring Spring是一個開源的Java EE開發(fā)框架秸苗。Spring框架的核心功能可以應用在任何Jav...
    jemmm閱讀 16,475評論 1 133