posts - 495,  comments - 11,  trackbacks - 0

          6.2.4 代理接口

          當(dāng)目標(biāo)Bean的實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)了接口后,Spring AOP可以為其創(chuàng)建JDK動(dòng)態(tài)代理,而無(wú)須使用CGLIB創(chuàng)建的代理,這種代理稱(chēng)為代理接口。

          創(chuàng)建AOP代理必須指定兩個(gè)屬性:目標(biāo)Bean和處理。實(shí)際上,很多AOP框架都以攔截器作為處理。因?yàn)镾pring AOP與IoC容器的良好整合,因此配置代理Bean時(shí),完全可以利用依賴(lài)注入來(lái)管理目標(biāo)Bean和攔截器Bean。

          下面的示例演示了基于A(yíng)OP的權(quán)限認(rèn)證,它是簡(jiǎn)單的TestService接口,該接口模擬Service組件,該組件內(nèi)包含兩個(gè)方法:

          ?? ● 查看數(shù)據(jù)。

          ?? ● 修改數(shù)據(jù)。

          接口的源代碼如下:

          //Service組件接口

          public interface TestService

          {

          ??? //查看數(shù)據(jù)

          ??? void view();

          ??? //修改數(shù)據(jù)

          ??? void modify();

          }

          該接口的實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)兩個(gè)方法。因?yàn)槠拗疲臼纠⑽达@示出完整的查看數(shù)據(jù)和修改數(shù)據(jù)的持久層操作,僅僅在控制臺(tái)打印兩行信息。實(shí)際的項(xiàng)目實(shí)現(xiàn)中,兩個(gè)方法的實(shí)現(xiàn)則改成對(duì)持久層組件的調(diào)用,這不會(huì)影響示例程序的效果。實(shí)現(xiàn)類(lèi)的源代碼如下:

          TestService接口的實(shí)現(xiàn)類(lèi)

          public class TestServiceImpl implements TestService

          {

          ??? //實(shí)現(xiàn)接口必須實(shí)現(xiàn)的方法

          ??? public void view()

          ??? {

          ??????? System.out.println("用戶(hù)查看數(shù)據(jù)");

          ??? }

          ??? //實(shí)現(xiàn)接口必須實(shí)現(xiàn)的方法

          ??? public void modify()

          ??? {

          ??????? System.out.println("用戶(hù)修改數(shù)據(jù)");

          ??? }

          }

          示例程序采用Around 處理作為攔截器,攔截器中使用依賴(lài)注入獲得當(dāng)前用戶(hù)名。實(shí)際Web應(yīng)用中,用戶(hù)應(yīng)該從session中讀取。這不會(huì)影響示例代碼的效果。攔截器源代碼如下:

          public class AuthorityInterceptor implements MethodInterceptor

          {

          ??? //當(dāng)前用戶(hù)名

          ??? private String user;

          ??? //依賴(lài)注入所必需的setter方法

          ??? public void setUser(String user)

          ??? {

          ??????? this.user = user;

          ??? }

          ??? public Object invoke(MethodInvocation invocation) throws Throwable

          ??? {

          ??????? //獲取當(dāng)前攔截的方法名

          ??????? String methodName = invocation.getMethod().getName();

          ??????? //下面執(zhí)行權(quán)限檢查

          ??????? //對(duì)既不是管理員,也不是注冊(cè)用戶(hù)的情況

          ??????? if (!user.equals("admin") && !user.equals("registedUser"))

          ??????? {

          ??????????? System.out.println("您無(wú)權(quán)執(zhí)行該方法");

          ??????????? return null;

          ??????? }

          ??????? //對(duì)僅僅是注冊(cè)用戶(hù),調(diào)用修改數(shù)據(jù)的情況

          ??????? else if (user.equals("registedUser") && methodName.equals
          ??????? ("modify"))

          ??????? {

          ??????????? System.out.println("您不是管理員,無(wú)法修改數(shù)據(jù)");

          ??????????? return null;

          ??????? }

          ??????? //對(duì)管理員或注冊(cè)用戶(hù),查看數(shù)據(jù)的情況

          ??????? else

          ??????? {

          ??????????? return invocation.proceed();

          ??????? }

          ??? }

          }

          TestAction類(lèi)依賴(lài)TestService。因篇幅關(guān)系,此處不給出TestAction的接口的源代碼,TestActionImpl的源代碼如下:

          public class TestActionImpl

          {

          ??? //將TestService作為成員變量,面向接口編程

          ??? private TestService ts;

          ??? //依賴(lài)注入的setter方法

          ??? public void setTs(TestService ts)

          ??? {

          ??????? this.ts = ts;

          ??? }

          ??? //修改數(shù)據(jù)

          ??? public void modify()

          ??? {

          ??????? ts.modify();

          ??? }

          ??? //查看數(shù)據(jù)

          ??? public void view()

          ??? {

          ??????? ts.view();

          ??? }

          }

          配置文件如下:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <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">

          ??? <!-- 配置目標(biāo)Bean -->

          ??? <bean id="serviceTarget" class="lee.TestServiceImpl"/>

          ??? <!-- 配置攔截器,攔截器作為處理使用 -->

          ??? <bean id="authorityInterceptor" class="lee.AuthorityInterceptor">

          ??????? <property name="user" value="admin"/>

          ??? </bean>

          ??? <!-- 配置代理工廠(chǎng)Bean,負(fù)責(zé)生成AOP代理 -->

          ??? <bean id="service" class="org.springframework.aop.framework.
          ??? ProxyFactoryBean">

          ??????? <!-- 指定AOP代理所實(shí)現(xiàn)的接口 -->

          ??????? <property name="proxyInterfaces" value="lee.TestService"/>

          ??????? <!-- 指定AOP代理所代理的目標(biāo)Bean -->

          ??????? <property name="target" ref="serviceTarget"/>

          ??????? <!-- AOP代理所需要的攔截器列表 -->

          ??????? <property name="interceptorNames">

          ??????????? <list>

          ??????????????? <value>authorityInterceptor</value>

          ??????????? </list>

          ??????? </property>

          ??? </bean>

          ??? <!-- 配置Action Bean,該Action依賴(lài)TestService Bean -->

          ??? <bean id="testAction" class="lee.TestActionImpl">

          ??????? <!-- 此處注入的是依賴(lài)代理Bean -->

          ??????? <property name="ts" ref="service"/>

          ??? </bean>

          </beans>

          主程序請(qǐng)求testAction Bean,然后調(diào)用該Bean的兩個(gè)方法,主程序如下:

          public class BeanTest

          {

          ??? public static void main(String[] args)throws Exception

          ??? {

          ??????? //創(chuàng)建Spring容器實(shí)例

          ??????? ApplicationContext ctx = new FileSystemXmlApplicationContext
          ??????? ("bean.xml");

          ??????? //獲得TestAction bean

          ??????? TestAction ta = (TestAction)ctx.getBean("testAction");

          ??????? //調(diào)用bean的兩個(gè)測(cè)試方法

          ??????? ta.view();

          ??????? ta.modify();

          ??? }

          }

          程序執(zhí)行結(jié)果如下:

          [java] 用戶(hù)查看數(shù)據(jù)

          [java] 用戶(hù)修改數(shù)據(jù)

          代理似乎沒(méi)有發(fā)揮任何作用。因?yàn)榕渲梦募械漠?dāng)前用戶(hù)是admin,admin用戶(hù)具備訪(fǎng)問(wèn)和修改數(shù)據(jù)的權(quán)限,因此代理并未阻止訪(fǎng)問(wèn)。將配置文件中的admin修改成registed- User,再次執(zhí)行程序,得到如下結(jié)果:

          [java] 用戶(hù)查看數(shù)據(jù)

          [java] 您不是管理員,無(wú)法修改數(shù)據(jù)

          代理阻止了registedUser修改數(shù)據(jù),查看數(shù)據(jù)可以執(zhí)行。將registedUser修改成其他用戶(hù),執(zhí)行程序,看到如下結(jié)果:

          [java] 您無(wú)權(quán)執(zhí)行該方法

          [java] 您無(wú)權(quán)執(zhí)行該方法

          代理阻止用戶(hù)對(duì)兩個(gè)方法的執(zhí)行。基于A(yíng)OP的權(quán)限檢查,可以降低程序的代碼量,因?yàn)闊o(wú)須每次調(diào)用方法之前,手動(dòng)編寫(xiě)權(quán)限檢查代碼;同時(shí),權(quán)限檢查與業(yè)務(wù)邏輯分離,提高了程序的解耦。

          示例中的目標(biāo)Bean被暴露在容器中,可以被客戶(hù)端代碼直接訪(fǎng)問(wèn)。為了避免客戶(hù)端代碼直接訪(fǎng)問(wèn)目標(biāo)Bean,可以將目標(biāo)Bean定義成代理工廠(chǎng)的嵌套Bean,修改后的配置文件如下:

          <?xml version="1.0" encoding="GBK"?>

          <!-- 指定Spring配置文件的根元素,以及Spring配置文件的Schema信息 -->

          <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="authorityInterceptor" class="lee.AuthorityInterceptor">

          ??????? <property name="user" value="admin"/>

          ??? </bean>

          ??? <!-- 配置代理工廠(chǎng)Bean,該工廠(chǎng)Bean將負(fù)責(zé)創(chuàng)建目標(biāo)Bean的代理 -->

          ??? <bean id="service" class="org.springframework.aop.framework.
          ??? ProxyFactoryBean">

          ??????? <!-- 指定AOP代理所實(shí)現(xiàn)的接口 -->

          ??????? <property name="proxyInterfaces" value="lee.TestService"/>

          ??????? <property name="target">

          ??????????? <!-- 以嵌套Bean的形式定義目標(biāo)Bean,避免客戶(hù)端直接訪(fǎng)問(wèn)目標(biāo)Bean -->

          ??? ??????? <bean class="lee.TestServiceImpl"/>

          ??????? </property>

          ??????? <!-- AOP代理所需要的攔截器列表 -->

          ??????? <property name="interceptorNames">

          ??????????? <list>

          ??????????????? <value>authorityInterceptor</value>

          ??????????? </list>

          ??????? </property>

          ??? </bean>

          ??? <!-- 配置Action Bean,該Action依賴(lài)TestService Bean -->

          ??? <bean id="testAction" class="lee.TestActionImpl">

          ??????? <!-- 此處注入的是依賴(lài)代理Bean -->

          ??????? <property name="ts" ref="service"/>

          ??? </bean>

          </beans>

          由上面介紹的內(nèi)容可見(jiàn),Spring的AOP是對(duì)JDK動(dòng)態(tài)代理模式的深化。通過(guò)Spring AOP組件,允許通過(guò)配置文件管理目標(biāo)Bean和AOP所需的處理。

          下面將繼續(xù)介紹如何為沒(méi)有實(shí)現(xiàn)接口的目標(biāo)Bean創(chuàng)建CGLIB代理。

          6.2.5 代理類(lèi)

          如果目標(biāo)類(lèi)沒(méi)有實(shí)現(xiàn)接口,則無(wú)法創(chuàng)建JDK動(dòng)態(tài)代理,只能創(chuàng)建CGLIB代理。如果需要沒(méi)有實(shí)現(xiàn)接口的Bean實(shí)例生成代理,配置文件中應(yīng)該修改如下兩項(xiàng):

          ?? ● 去掉<property name="proxyInterfaces"/>聲明。因?yàn)椴辉俅斫涌冢虼耍颂幍呐渲脹](méi)有意義。

          ?? ● 增加<property name="proxyTargetClass">子元素,并設(shè)其值為true,通過(guò)該元素強(qiáng)制使用CGLIB代理,而不是JDK動(dòng)態(tài)代理。

          注意:最好面向接口編程,不要面向類(lèi)編程。同時(shí),即使在實(shí)現(xiàn)接口的情況下,也可強(qiáng)制使用CGLIB代理。

          CGLIB代理在運(yùn)行期間產(chǎn)生目標(biāo)對(duì)象的子類(lèi),該子類(lèi)通過(guò)裝飾器設(shè)計(jì)模式加入到Advice中。因?yàn)镃GLIB代理是目標(biāo)對(duì)象的子類(lèi),則必須考慮保證如下兩點(diǎn):

          ?? ● 目標(biāo)類(lèi)不能聲明成final,因?yàn)閒inal類(lèi)不能被繼承,無(wú)法生成代理。

          ?? ● 目標(biāo)方法也不能聲明成final,final方法不能被重寫(xiě),無(wú)法得到處理。

          當(dāng)然,為了需要使用CGLIB代理,應(yīng)用中應(yīng)添加CGLIB二進(jìn)制Jar文件。

          6.2.6 使用BeanNameAutoProxyCreator自動(dòng)創(chuàng)建代理

          這是一種自動(dòng)創(chuàng)建事務(wù)代理的方式,一旦在容器中配置了BeanNameAutoProxyCreator實(shí)例,該實(shí)例將會(huì)對(duì)指定名字的Bean實(shí)例自動(dòng)創(chuàng)建代理。實(shí)際上,BeanNameAutoProxyCreator是一個(gè)Bean后處理器,理論上它會(huì)對(duì)容器中所有的Bean進(jìn)行處理,實(shí)際上它只對(duì)指定名字的Bean實(shí)例創(chuàng)建代理。

          BeanNameAutoProxyCreator根據(jù)名字自動(dòng)生成事務(wù)代理,名字匹配支持通配符。

          與ProxyFactoryBean一樣,BeanNameAutoProxyCreator需要一個(gè)interceptorNames屬性,該屬性名雖然是“攔截器”,但并不需要指定攔截器列表,它可以是Advisor或任何處理類(lèi)型。

          下面是使用BeanNameAutoProxyCreator的配置片段:

          <!-- 定義事務(wù)攔截器bean -->

          <bean id="transactionInterceptor"

          ??? class="org.springframework.transaction.interceptor.
          ??? TransactionInterceptor">

          ??? <!-- 事務(wù)攔截器bean需要依賴(lài)注入一個(gè)事務(wù)管理器 -->

          ??? <property name="transactionManager" ref="transactionManager"/>

          ??? <property name="transactionAttributes">

          ??????? <!-- 下面定義事務(wù)傳播屬性 -->

          ??????? <props>

          ??????????? <prop key="insert*">PROPAGATION_REQUIRED </prop>

          ??????????? <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

          ??????????? <prop key="*">PROPAGATION_REQUIRED</prop>

          ??????? </props>

          ??? </property>

          ??? </bean>

          <!-- 定義BeanNameAutoProxyCreator Bean,它是一個(gè)Bean后處理器,

          ??????? 負(fù)責(zé)為容器中特定的Bean創(chuàng)建AOP代理 -->

          <bean class="org.springframework.aop.framework.autoproxy.
          ??? BeanNameAutoProxyCreator">

          ??? <!-- 指定對(duì)滿(mǎn)足哪些bean name的bean自動(dòng)生成業(yè)務(wù)代理 -->

          ??? <property name="beanNames">

          ??????? <list>

          ??????????? <!-- 下面是所有需要自動(dòng)創(chuàng)建事務(wù)代理的Bean -->

          ??????? ??? <value>core-services-applicationControllerSevice</value>

          ??????? ??? <value>core-services-deviceService</value>

          ??????? ??? <value>core-services-authenticationService</value>

          ??????? ??? <value>core-services-packagingMessageHandler</value>

          ??????? ??? <value>core-services-sendEmail</value>

          ??????? ??? <value>core-services-userService</value>

          ??????????? <!-- 此處可增加其他需要自動(dòng)創(chuàng)建事務(wù)代理的Bean -->

          ??????? </list>

          ??? </property>

          ??? <!-- 下面定義BeanNameAutoProxyCreator所需的攔截器 -->

          ??? <property name="interceptorNames">

          ??????? <list>

          ??????????? <value>transactionInterceptor</value>

          ??????????? <!-- 此處可增加其他新的Interceptor -->

          ??????? </list>

          ??? </property>

          </bean>

          上面的片段是使用BeanNameAutoProxyCreator自動(dòng)創(chuàng)建事務(wù)代理的片段。Transaction- Interceptor用來(lái)定義事務(wù)攔截器,定義事務(wù)攔截器時(shí)傳入事務(wù)管理器Bean,也指定事務(wù)傳播屬性。

          通過(guò)BeanNameAutoProxyCreator定義Bean后處理器,定義該Bean后處理器時(shí),通過(guò)beanNames屬性指定有哪些目標(biāo)Bean生成事務(wù)代理;還需要指定“攔截器鏈”,該攔截器鏈可以由任何處理組成。

          定義目標(biāo)Bean還可使用通配符,使用通配符的配置片段如下所示:

          <!-- 定義BeanNameAutoProxyCreator Bean,它是一個(gè)Bean后處理器,

          ??????? 負(fù)責(zé)為容器中特定的Bean創(chuàng)建AOP代理 -->

          <bean class="org.springframework.aop.framework.autoproxy.
          BeanNameAutoProxyCreator">

          ??? <!-- 指定對(duì)滿(mǎn)足哪些bean name的bean自動(dòng)生成業(yè)務(wù)代理 -->

          ??? <property name="beanNames">

          ??????? <!-- 此處使用通配符確定目標(biāo)bean -->

          ??????? <value>*DAO,*Service,*Manager</value>

          ??? </property>

          ??? <!-- 下面定義BeanNameAutoProxyCreator所需的事務(wù)攔截器 -->

          ??? <property name="interceptorNames">

          ??????? <list>

          ??????????? <value>transactionInterceptor</value>

          ??????????? <!-- 此處可增加其他新的Interceptor -->

          ??????? </list>

          ??? </property>

          </bean>

          上面的配置片段中,所有名字以DAO、Service、Manager結(jié)尾的bean,將由該“bean后處理器”為其創(chuàng)建事務(wù)代理。目標(biāo)bean不再存在,取而代之的是目標(biāo)bean的事務(wù)代理。通過(guò)這種方式,不僅可以極大地降低配置文件的繁瑣,而且可以避免客戶(hù)端代碼直接調(diào)用目標(biāo)bean。

          注意:雖然上面的配置片段是為目標(biāo)對(duì)象自動(dòng)生成事務(wù)代理。但這不是唯一的,如果有需要,可以為目標(biāo)對(duì)象生成任何的代理。BeanNameAutoProxyCreator為目標(biāo)對(duì)象生成怎樣的代理,取決于傳入怎樣的處理Bean,如果傳入事務(wù)攔截器,則生成事務(wù)代理Bean;否則將生成其他代理,在后面的實(shí)例部分,讀者將可以看到大量使用BeanNameAutoProxy- Creator創(chuàng)建的權(quán)限檢查代理。

          6.2.7 使用DefaultAdvisorAutoProxyCreator自動(dòng)創(chuàng)建代理

          Spring還提供了另一個(gè)Bean后處理器,它也可為容器中的Bean自動(dòng)創(chuàng)建代理。相比之下,DefaultAdvisorAutoProxyCreator是更通用、更強(qiáng)大的自動(dòng)代理生成器。它將自動(dòng)應(yīng)用于當(dāng)前容器中的advisor,不需要在DefaultAdvisorAutoProxyCreator定義中指定目標(biāo)Bean的名字字符串。

          這種定義方式有助于配置的一致性,避免在自動(dòng)代理創(chuàng)建器中重復(fù)配置目標(biāo)Bean 名。

          使用該機(jī)制包括:

          ?? ● 配置DefaultAdvisorAutoProxyCreator bean定義。

          ?? ● 配置任何數(shù)目的Advisor,必須是Advisor,不僅僅是攔截器或其他處理。因?yàn)椋仨毷褂们腥朦c(diǎn)檢查處理是否符合候選Bean定義。

          DefaultAdvisorAutoProxyCreator計(jì)算Advisor包含的切入點(diǎn),檢查處理是否應(yīng)該被應(yīng)用到業(yè)務(wù)對(duì)象,這意味著任何數(shù)目的Advisor都可自動(dòng)應(yīng)用到業(yè)務(wù)對(duì)象。如果Advisor中沒(méi)有切入點(diǎn)符合業(yè)務(wù)對(duì)象的方法,這個(gè)對(duì)象就不會(huì)被代理。如果增加了新的業(yè)務(wù)對(duì)象,只要它們符合切入點(diǎn)定義,DefaultAdvisorAutoProxyCreator將自動(dòng)為其生成代理,無(wú)須額外?? 配置。

          當(dāng)有大量的業(yè)務(wù)對(duì)象需要采用相同處理,DefaultAdvisorAutoProxyCreator是非常有用的。一旦定義恰當(dāng),直接增加業(yè)務(wù)對(duì)象,而不需要額外的代理配置,系統(tǒng)自動(dòng)為其增加???? 代理。

          <beans>

          ??? <!-- 定義Hibernate局部事務(wù)管理器,可切換到JTA全局事務(wù)管理器 -->

          ??? <bean id="transactionManager"

          ???????? class="org.springframework.orm.hibernate3.
          ??????? HibernateTransactionManager">

          ??????? <!-- 定義事務(wù)管理器時(shí),依賴(lài)注入SessionFactory -->

          ???????? <property name="sessionFactory" ref bean="sessionFactory"/>

          ??? </bean>

          ??? <!-- 定義事務(wù)攔截器 -->

          ??? <bean id="transactionInterceptor"

          ??????? class="org.springframework.transaction.interceptor.
          ??????? TransactionInterceptor">

          ???????? <property name="transactionManager" ref="transactionManager"/>

          ???????? <property name="transactionAttributeSource">

          ??????????? <props>

          ??????????????? <prop key="*">PROPAGATION_REQUIRED</prop>

          ????? ??????????? <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>

          ??????????? </props>

          ??????? </property>

          ??? </bean>

          ??? <!-- 定義DefaultAdvisorAutoProxyCreator Bean,這是一個(gè)Bean后處理器 -->

          ??? <bean class="org.springframework.aop.framework.autoproxy.
          ??? DefaultAdvisorAutoProxyCreator"/>

          ??? <!-- 定義事務(wù)Advisor -->

          ??? <bean class="org.springframework.transaction.interceptor.
          ??? TransactionAttributeSourceAdvisor">

          ??? ???? <property name="transactionInterceptor" ref=
          ??????? "transactionInterceptor"/>

          ??? </bean>

          ??? <!-- 定義額外的Advisor>

          ??? <bean id="customAdvisor" class="lee.MyAdvisor"/>

          </beans>

          DefaultAdvisorAutoProxyCreator支持過(guò)濾和排序。如果需要排序,可讓Advisor實(shí)現(xiàn)org.springframework.core.Ordered接口來(lái)確定順序。TransactionAttributeSourceAdvisor已經(jīng)實(shí)現(xiàn)Ordered接口,因此可配置其順序,默認(rèn)是不排序。

          采用這樣的方式,一樣可以避免客戶(hù)端代碼直接訪(fǎng)問(wèn)目標(biāo)Bean,而且配置更加簡(jiǎn)潔。只要目標(biāo)Bean符合切入點(diǎn)檢查,Bean后處理器自動(dòng)為目標(biāo)Bean創(chuàng)建代理,無(wú)須依次指定目標(biāo)Bean名。

          注意:Spring也支持以編程方式創(chuàng)建AOP代理,但這種方式將AOP代理所需要的目標(biāo)對(duì)象和處理Bean等對(duì)象的耦合降低到代碼層次,因此不推薦使用。如果讀者需要深入了解如何通過(guò)編程方式創(chuàng)建AOP代理,請(qǐng)參閱筆者所著的《Spring2.0寶典》。

          posted on 2009-07-19 10:16 jadmin 閱讀(94) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 马山县| 墨竹工卡县| 新宾| 桑日县| 滦南县| 田东县| 乐至县| 若羌县| 诏安县| 盐源县| 洛扎县| 高清| 环江| 开化县| 肥东县| 汝南县| 邵阳县| 台州市| 通河县| 娄烦县| 永济市| 怀仁县| 巧家县| 博白县| 宝应县| 康乐县| 临朐县| 禄劝| 公安县| 大兴区| 安福县| 察隅县| 西丰县| 万宁市| 南郑县| 云龙县| 阿坝| 久治县| 青龙| 辽宁省| 泊头市|