Spring Bean 的裝配方式以及Autowired與Resource的使用及區(qū)別

1.Spring的自動裝配

在Spring的使用中季二,如果要將一個bean實例化檩咱,可以通過配置文件,也可以通過在java代碼里面的注解來實現(xiàn)胯舷,Spring能夠根據(jù)自動協(xié)作這些bean之間的關(guān)系刻蚯,這種自動協(xié)作的過程,也稱之為自動裝配桑嘶。
自動裝配模式有如下四種模式:

模式 說明
no no表示關(guān)閉自動裝配選項炊汹,必須通過顯示的設(shè)置才能確認依賴關(guān)系。這也是采用xml配置的默認選項逃顶。
byname 基于bean的名稱name進行注入讨便,在進行Bean的自動裝配時,將屬性的name在配置文件中搜索匹配的Bean,如果找到name一致的bean,則進行注入以政,如果找不打到霸褒,則會拋出異常。
byType 基于bean的類型進行注入盈蛮,在bean中自動裝配屬性的時候废菱,將定義的屬性類型與配置文件中定義的bean進行匹配,如果類型一致,就在屬性中注入昙啄,如果沒有找到這樣的bean,就拋出異常穆役。
constructor 通過構(gòu)造函數(shù)自動裝配bean,這個操作與ByType是一致的,在自動裝配的過程中梳凛,將查找構(gòu)造函數(shù)的參數(shù)類型耿币,然后對所有構(gòu)造函數(shù)參數(shù)執(zhí)行自動裝配。

有三種方式可以實現(xiàn)spring Bean的裝配過程:

  • xml配置
  • @Autowired
  • @Resource

2.xml配置實現(xiàn)裝配

首先定義了三個類韧拒, 分別為:

表示用戶關(guān)系的User類 :

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class User {
    //編號
    private int id;
    //姓名
    private String name;
    //年齡
    private int age;

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

表示角色的Role類:

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class Role {
    //角色ID
    private int roleId;
    //角色名稱
    private String roleName;
}

以及表示用戶角色關(guān)聯(lián)關(guān)系的UserRole類:

package com.dhb.gts.javacourse.week5.springbean.v1;

import lombok.Data;

@Data
public class UserRole {
    //用戶
    private User user;
    //角色
    private Role role;

    public UserRole() {
    }

    public UserRole(User user, Role role) {
        this.user = user;
        this.role = role;
    }
}

2.1 xml實現(xiàn)基本的裝配

配置xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="張三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理員"/>
    </bean>
    
    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" >
        <property name="role" ref="role"/>
        <property name="user" ref="user"/>
    </bean>
    
</beans>

測試類:

package com.dhb.gts.javacourse.week5.springbean.v1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XmlTest1 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-1.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
    }

}


這種方式需要在xml中對每一個屬性進行配置淹接,首先通過property裝配了User和Role,UserRole對象的兩個屬性role和user通過property進行關(guān)聯(lián)叛溢。這樣就能實現(xiàn)spring中最基本的一種裝配方式塑悼。
可以通過XmlTest1類進行測試,確認裝配的正確性楷掉。

UserRole(user=User(id=1, name=張三, age=22), role=Role(roleId=1, roleName=管理員))

2.2 xml通過byName實現(xiàn)自動裝配

xml配置代碼:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="張三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理員"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="byName"/>
    
</beans>

測試代碼:

package com.dhb.gts.javacourse.week5.springbean.v1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XmlTest2 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-2.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
    }

}


這種裝配方式不用在UserRole中指定user和role對應(yīng)的具體類厢蒜,只需要增加一個屬性:autowire="byName",就能在自動裝配的過程中烹植,將根據(jù)UserRole的屬性的name查找context中name與之對應(yīng)的bean進行裝配斑鸦。
測試結(jié)果如下:

UserRole(user=User(id=1, name=張三, age=22), role=Role(roleId=1, roleName=管理員))

2.3 xml通過byType實現(xiàn)自動裝配

xml配置代碼:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="張三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理員"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="byType"/>
    
</beans>

測試代碼:

package com.dhb.gts.javacourse.week5.springbean.v1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XmlTest3 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-3.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
    }

}


這種裝配方式同樣不用在UserRole中指定user和role對應(yīng)的具體類,只需要增加一個屬性:autowire="byType"草雕,就能在自動裝配的過程中巷屿,將根據(jù)UserRole成員變量的類型查找context中類型與之對應(yīng)的bean進行裝配。
需要注意的是墩虹,byName方式可以確保bean的唯一性嘱巾,但是byType方式,無法確保bean的唯一性诫钓,如果出現(xiàn)多個bean的類型相同旬昭,則會報錯。
測試結(jié)果如下:

UserRole(user=User(id=1, name=張三, age=22), role=Role(roleId=1, roleName=管理員))

2.4 xml通過constructor實現(xiàn)自動裝配

xml配置代碼:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.dhb.gts.javacourse.week5.springbean.v1.User">
        <constructor-arg name="id" value="001"/>
        <constructor-arg name="name" value="張三"/>
        <constructor-arg name="age" value="22"/>
    </bean>
    
    <bean id="role" class="com.dhb.gts.javacourse.week5.springbean.v1.Role">
        <property name="roleId" value="1"/>
        <property name="roleName" value="管理員"/>
    </bean>

    <bean id="userRole" class="com.dhb.gts.javacourse.week5.springbean.v1.UserRole" autowire="constructor">
        <constructor-arg name="user" ref="user"/>
        <constructor-arg name="role" ref="role"/>
    </bean>
</beans>

測試代碼:

package com.dhb.gts.javacourse.week5.springbean.v1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class XmlTest4 {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v1-4.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
    }

}


這種裝配方式同樣不用在UserRole中指定user和role對應(yīng)的具體類尖坤,只需要增加一個屬性:autowire="constructor"稳懒,就能在自動裝配的過程中,將根據(jù)UserRole構(gòu)造函數(shù)參數(shù)表constructor-arg配置的name查找context中name與之對應(yīng)的bean進行裝配慢味。
測試結(jié)果如下:

UserRole(user=User(id=1, name=張三, age=22), role=Role(roleId=1, roleName=管理員))

2.@Autowired實現(xiàn)裝配

@Autowired是采用byType實現(xiàn)的自動裝配场梆,在裝配的過程中,通過類型進行匹配纯路。
同樣或油,定義了Role

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class Role {
    //角色ID
    @Value("2")
    private Integer roleId;
    //角色名稱
    @Value("用戶")
    private String roleName;
}

以及User

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class User {
    //編號
    private Integer id;
    //姓名
    private String name;
    //年齡
    private Integer age;

    @Autowired
    public User(@Value("1") int id, @Value("用戶") String name,@Value("22")  int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

2.1 注解在屬性上

UserRole代碼如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Data
public class UserRole {
    //用戶
    @Autowired
    private User user;
    //角色
    @Autowired
    private Role role;

    public UserRole() {
    }

    public UserRole(User user, Role role) {
        this.user = user;
        this.role = role;
    }
}   

如上所示,只需要在UserRole的屬性上增加@Autpwired,在context中查找與屬性類型一致的bean,就可以實現(xiàn)UserRole的自動裝配驰唬。

2.2 注解在構(gòu)造函數(shù)上

UserRole代碼如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Data
public class UserRole1 {
    //用戶
    private User user;
    //角色
    private Role role;

    public UserRole1() {
    }

    @Autowired
    public UserRole1(User user, Role role) {
        this.user = user;
        this.role = role;
    }
}

注解在構(gòu)造函數(shù)上顶岸,等價于xml配置中的constructor配置腔彰。通過構(gòu)造函數(shù)的屬性值的類型去查找context中的bean。

2.3 注解在Set方法上

UserRole代碼如下:

package com.dhb.gts.javacourse.week5.springbean.v2;

import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@ToString
public class UserRole2 {
   //用戶
   private User user;
   //角色
   private Role role;


   public User getUser() {
       return user;
   }

   @Autowired
   public void setUser(User user) {
       this.user = user;
   }

   public Role getRole() {
       return role;
   }

   @Autowired
   public void setRole(Role role) {
       this.role = role;
   }

   public UserRole2() {
   }
   
   public UserRole2(User user, Role role) {
       this.user = user;
       this.role = role;
   }
}

AutoWired也可以注解在set方法上來實現(xiàn)自動裝配辖佣。根據(jù)set方法的參數(shù)霹抛,從context中選擇type與之一致的bean實現(xiàn)裝配。

2.4 測試

測試代碼如下:

public class AutowiredTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v2.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
        UserRole1 userRole1 = (UserRole1) context.getBean("userRole1");
        System.out.println(userRole1.toString());
        UserRole2 userRole2 = (UserRole2) context.getBean("userRole2");
        System.out.println(userRole2.toString());
    }
}

xml配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.dhb.gts.javacourse.week5.springbean.v2">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
</beans>

測試結(jié)果:

UserRole(user=User(id=1, name=用戶, age=22), role=Role(roleId=2, roleName=用戶))
UserRole1(user=User(id=1, name=用戶, age=22), role=Role(roleId=2, roleName=用戶))
UserRole2(user=User(id=1, name=用戶, age=22), role=Role(roleId=2, roleName=用戶))

3.@Resource實現(xiàn)裝配

同樣卷谈,通過J2EE的@Resource標(biāo)簽也能實現(xiàn)Bean的裝配杯拐,但是需要注意的是,這個注解不支持構(gòu)造函數(shù)世蔗,只支持屬性或者set方法端逼。需要注意的是,@Resource默認是采用byName的方式從contect中查找bean.
角色類:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class Role {
    //角色ID
    @Value("2")
    private Integer roleId;
    //角色名稱
    @Value("用戶")
    private String roleName;
}

用戶類:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
@Data
public class User {
    //編號
    private Integer id;
    //姓名
    private String name;
    //年齡
    private Integer age;

    @Autowired
    public User(@Value("1") int id, @Value("用戶") String name,@Value("22")  int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
}

3.1 注解在屬性上

代碼如下:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.Data;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Data
public class UserRole {
    //用戶
    @Resource(type = User.class)
    private User user;
    //角色
    @Resource(name = "role")
    private Role role;

    public UserRole() {
    }

    public UserRole(User user, Role role) {
        this.user = user;
        this.role = role;
    }
}

3.2 注解在set方法上

代碼如下:

package com.dhb.gts.javacourse.week5.springbean.v3;

import lombok.ToString;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@ToString
public class UserRole1 {
    //用戶
    private User user;
    //角色
    private Role role;

    public UserRole1() {
    }

    public User getUser() {
        return user;
    }

    @Resource
    public void setUser(User user) {
        this.user = user;
    }

    public Role getRole() {
        return role;
    }

    @Resource
    public void setRole(Role role) {
        this.role = role;
    }
    
    public UserRole1(User user, Role role) {
        this.user = user;
        this.role = role;
    }
}

3.3 @Resource測試:

測試類:

public class ResourceTest {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("app-v3.xml");
        UserRole userRole = (UserRole) context.getBean("userRole");
        System.out.println(userRole.toString());
        UserRole1 userRole1 = (UserRole1) context.getBean("userRole1");
        System.out.println(userRole1.toString());
    }
}

測試配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.dhb.gts.javacourse.week5.springbean.v3">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
</beans>

測試結(jié)果:

UserRole(user=User(id=1, name=用戶, age=22), role=Role(roleId=2, roleName=用戶))
UserRole1(user=User(id=1, name=用戶, age=22), role=Role(roleId=2, roleName=用戶))

4.@Autowired與@Resource的比較

二者對比如下:

  • @Autowired與@Resource都可以用來裝配bean. 都可以寫在字段上,或者在setter方法上污淋。 但是@Resource不支持在構(gòu)造函數(shù)上裝配顶滩。
  • @Autowired默認按類型裝配(這個注解是屬業(yè)spring的),默認情況下必須要求依賴對象必須存在寸爆,如果要允許null 值礁鲁,可以設(shè)置它的required屬性為false,如:@Autowired(required=false) 而昨。如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進行使用救氯。
  • @Resource(這個注解屬于J2EE的),默認安照名稱進行裝配歌憨,名稱可以通過name屬性進行指定, 如果沒有指定name屬性墩衙,當(dāng)注解寫在字段上時务嫡,默認取字段名進行按照名稱查找,如果注解寫在setter方法上默認取屬性名進行裝配漆改。 當(dāng)找不到與名稱匹配的bean時才按照類型進行裝配心铃。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市挫剑,隨后出現(xiàn)的幾起案子去扣,更是在濱河造成了極大的恐慌,老刑警劉巖樊破,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愉棱,死亡現(xiàn)場離奇詭異,居然都是意外死亡哲戚,警方通過查閱死者的電腦和手機奔滑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來顺少,“玉大人朋其,你說我怎么就攤上這事王浴。” “怎么了梅猿?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵氓辣,是天一觀的道長。 經(jīng)常有香客問我袱蚓,道長钞啸,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任癞松,我火速辦了婚禮爽撒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘响蓉。我一直安慰自己硕勿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布枫甲。 她就那樣靜靜地躺著源武,像睡著了一般。 火紅的嫁衣襯著肌膚如雪想幻。 梳的紋絲不亂的頭發(fā)上粱栖,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音脏毯,去河邊找鬼闹究。 笑死,一個胖子當(dāng)著我的面吹牛食店,可吹牛的內(nèi)容都是我干的渣淤。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吉嫩,長吁一口氣:“原來是場噩夢啊……” “哼价认!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起自娩,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤用踩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后忙迁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脐彩,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年动漾,在試婚紗的時候發(fā)現(xiàn)自己被綠了丁屎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡旱眯,死狀恐怖晨川,靈堂內(nèi)的尸體忽然破棺而出证九,到底是詐尸還是另有隱情,我是刑警寧澤共虑,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布愧怜,位于F島的核電站,受9級特大地震影響妈拌,放射性物質(zhì)發(fā)生泄漏拥坛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一尘分、第九天 我趴在偏房一處隱蔽的房頂上張望猜惋。 院中可真熱鬧,春花似錦培愁、人聲如沸著摔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谍咆。三九已至,卻和暖如春私股,著一層夾襖步出監(jiān)牢的瞬間摹察,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工倡鲸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留供嚎,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓峭状,卻偏偏與公主長得像查坪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宁炫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,779評論 2 354

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