中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

2018網(wǎng)站外鏈怎么做谷歌seo顧問

2018網(wǎng)站外鏈怎么做,谷歌seo顧問,抖音橙子建站,律師如何做網(wǎng)絡(luò)推廣Day49 代理模式proxy 概念: 代理(Proxy)是一種設(shè)計(jì)模式,提供了對(duì)目標(biāo)對(duì)象另外的訪問方式,即通過代理對(duì)象訪問目標(biāo)對(duì)象.這樣做的好處是:可以在目標(biāo)對(duì)象實(shí)現(xiàn)的基礎(chǔ)上,增強(qiáng)額外的功能操作,即擴(kuò)展目標(biāo)對(duì)象的功能. 代理模式分為靜態(tài)代理和動(dòng)態(tài)代理…

Day49

代理模式proxy

概念: 代理(Proxy)是一種設(shè)計(jì)模式,提供了對(duì)目標(biāo)對(duì)象另外的訪問方式,即通過代理對(duì)象訪問目標(biāo)對(duì)象.這樣做的好處是:可以在目標(biāo)對(duì)象實(shí)現(xiàn)的基礎(chǔ)上,增強(qiáng)額外的功能操作,即擴(kuò)展目標(biāo)對(duì)象的功能.

代理模式分為靜態(tài)代理和動(dòng)態(tài)代理兩種 。

靜態(tài)代理

思路:對(duì)于同一個(gè)接口,代理類和被代理類都實(shí)現(xiàn)了這個(gè)接口,代理類中將被代理類對(duì)象持有為自己的屬性,這樣在使用方法的時(shí)候就可以在被代理類的方法前后加上增強(qiáng),即自己的方法邏輯。

以Speaker接口、ChineseSpeaker、AmericaSpeaker、ChinsesSpeakerProxy、AmericaSpeakerProxy為例,其中ChinsesSpeakerProxy、AmericaSpeakerProxy分別是ChineseSpeaker、AmericaSpeaker的代理類:

Speaker:

public interface Speaker {void speak();
}

ChineseSpeaker:

public class ChineseSpeaker implements Speaker{public void speak() {System.out.println("中文演講");}
}

ChinsesSpeakerProxy:

public class ChineseSpeakerProxy implements Speaker{private ChineseSpeaker speaker;public ChineseSpeakerProxy(ChineseSpeaker speaker) {this.speaker = speaker;}@Overridepublic void speak() {System.out.println("增強(qiáng)處理");speaker.speak();System.out.println("增強(qiáng)處理");}
}

可以看出,這種寫法每代理一個(gè)真實(shí)類就需要寫一個(gè)代理類,對(duì)于AmericaSpeaker,同樣要寫一個(gè)AmericaSpeakerProxy。如果對(duì)于功能增強(qiáng)的內(nèi)容完全相同,就可以使用一個(gè)對(duì)于Speaker接口通用的代理類CommonSpeakerProxy,利用多態(tài)完成代理。

public class CommonSpeakerProxy implements Speaker {private Speaker speaker;public CommonSpeakerProxy(Speaker speaker) {this.speaker = speaker;}@Overridepublic void speak() {System.out.println("前置功能增強(qiáng)");speaker.speak();System.out.println("后置功能增強(qiáng)");}
}

除了這種寫法外,還可以利用反射的思想來寫,利用多態(tài)通過接口實(shí)現(xiàn)類拿到方法,通過有參傳入的類對(duì)象,用method.invoke()方法完成代理。

假設(shè)這時(shí)再添加了Seller接口、ChineseSeller、AmericaSeller類及其代理類CommonSellerProxy

public class CommonSellerProxy implements Seller{private static Method method;private  Object seller;public CommonSellerProxy(Object seller){this.seller = seller;}static {try {method = Seller.class.getMethod("sell");} catch (NoSuchMethodException e) {e.printStackTrace();}}@Overridepublic void sell() {try {System.out.println("前置功能增強(qiáng)");method.invoke(seller);System.out.println("后置功能增強(qiáng)");} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);}}
}

可以看出,靜態(tài)代理每實(shí)現(xiàn)一個(gè)真實(shí)類的代理就需要寫一個(gè)代理類,如果代理的功能不同,就需要針對(duì)代理功能編寫多個(gè)類,十分復(fù)雜。那么有沒有一種方式使得在使用到代理的時(shí)候再去編寫代理的邏輯功能,而不是每次都去多寫一個(gè)類呢?這就是動(dòng)態(tài)代理的思想。

動(dòng)態(tài)代理

動(dòng)態(tài)代理又根據(jù)代理對(duì)象進(jìn)行劃分:

為接口做代理:JDK動(dòng)態(tài)代理

為類做代理:CGLIB動(dòng)態(tài)代理

JDK動(dòng)態(tài)代理

由于動(dòng)態(tài)代理和靜態(tài)代理差別較大,這里從靜態(tài)代理開始進(jìn)階優(yōu)化,直到達(dá)到動(dòng)態(tài)代理的范疇。

**靜態(tài)代理進(jìn)階:**思路:寫一個(gè)接口,接口中定義了代理重寫的方法,在代理類中以匿名內(nèi)部類的方式創(chuàng)建一個(gè)類對(duì)象作為自己持有的屬性,并用全參構(gòu)造要求使用時(shí)創(chuàng)建這個(gè)匿名內(nèi)部類(即重寫代理方法內(nèi)容),而代理類中就只需要調(diào)用接口的實(shí)現(xiàn)類的方法就行,不需要再寫明方法邏輯。

這個(gè)接口是jdk自帶的接口,在這里自己寫一遍,以更好地明白邏輯:

MethodInvocationHandler接口:

public interface MethodInvocationHandler {Object handle(Object target, Method method,Object[] args) throws Exception;
}

注意:這個(gè)方法的本質(zhì)是反射,利用method.invoke()方法進(jìn)行調(diào)用真實(shí)類的方法,再加上代理類的方法,因此參數(shù)為method.invoke()的參數(shù)。

ChineseSpeakerProxy代理類:

public class ChineseSpeakerProxy implements Speaker{private Speaker speaker;private MethodInvocationHandler handler;private static Method method;static {try {method = Speaker.class.getMethod("speak");} catch (NoSuchMethodException e) {throw new RuntimeException(e);}}public ChineseSpeakerProxy(Speaker speaker, MethodInvocationHandler handler) {this.speaker = speaker;this.handler = handler;}//如果有多個(gè)需要代理的方法就都要進(jìn)行重寫@Overridepublic void speak() {try {handler.handle(speaker,method,null);//由于真實(shí)類中的方法是無參的,所以這里的參數(shù)數(shù)組為空} catch (Exception e) {throw new RuntimeException(e);}}
}

使用:

public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();ChineseSpeakerProxy chineseSpeakerProxy = new ChineseSpeakerProxy(chineseSpeaker, new MethodInvocationHandler() {@Overridepublic Object handle(Object target, Method method, Object[] args) throws Exception {System.out.println("功能增強(qiáng)");method.invoke(target,args);System.out.println("功能增強(qiáng)");return null;}});chineseSpeakerProxy.speak();}

至此,對(duì)于同一個(gè)代理類的多個(gè)功能,實(shí)現(xiàn)了讓用戶自己寫增強(qiáng)方法的目的。但是對(duì)于一個(gè)真實(shí)類,如果要實(shí)現(xiàn)其代理,那還是要寫一個(gè)代理類,如果真實(shí)類很多,那就需要寫很多的代理類,代理繁多的問題依然存在。

如果這些代理類能夠使用代碼來生成,然后再編譯,再加載至 JVM 中,那么再多的代理也就不是問題了。

動(dòng)態(tài)代理

手動(dòng)寫一個(gè)能夠自動(dòng)創(chuàng)建代理類源碼的類,然后手動(dòng)完成編譯、加載的過程。(這些功能jdk的接口都實(shí)現(xiàn)了,這里只手寫一個(gè)自動(dòng)創(chuàng)建代理類源碼的類以便深刻理解)

因此,可以手動(dòng)寫一個(gè)能夠自動(dòng)創(chuàng)建代理類源碼的類,然后手動(dòng)完成編譯、加載的過程。(這些功能jdk的接口都實(shí)現(xiàn)了,這里只手寫一個(gè)自動(dòng)創(chuàng)建代理類源碼的類以便深刻理解)

package com.qf.proxy;import com.qf.proxy.dynamic.MethodInvocationHandler;import java.lang.reflect.Method;
import java.lang.reflect.Parameter;public class MyProxy {private static String generateProxyClass(Class<?> clazz){if(!clazz.isInterface()) throw new IllegalArgumentException(clazz.getName() + " 不是接口");StringBuilder builder = new StringBuilder();builder.append("package ").append(clazz.getPackage().getName()).append(";\n");builder.append("import ").append(Method.class.getName()).append(";\n");builder.append("import ").append(MethodInvocationHandler.class.getName()).append(";\n");builder.append("import ").append(MyProxy.class.getName()).append(";\n");builder.append("public class $proxy0 extends MyProxy implements ").append(clazz.getSimpleName()).append("{\n");StringBuilder staticBuilder = new StringBuilder();staticBuilder.append("static {\n");staticBuilder.append("try {\n");StringBuilder overrideMethodBuilder = new StringBuilder();Method[] methods = clazz.getMethods();for(int i=0; i<methods.length; i++){builder.append("private static Method m").append(i).append(";\n");staticBuilder.append("m").append(i).append("=Class.forName(\"").append(clazz.getName()).append("\").getMethod(\"").append(methods[i].getName()).append("\",");overrideMethodBuilder.append("\n@Override\n");overrideMethodBuilder.append("public ").append(methods[i].getReturnType().getSimpleName()).append(" ").append(methods[i].getName()).append("(");Parameter[] parameters = methods[i].getParameters();for(Parameter parameter : parameters){staticBuilder.append(parameter.getType().getSimpleName()).append(".class,");overrideMethodBuilder.append(parameter.getType().getSimpleName()).append(" ").append(parameter.getName()).append(",");}staticBuilder.deleteCharAt(staticBuilder.length()-1);staticBuilder.append(");\n");if(parameters.length > 0)overrideMethodBuilder.deleteCharAt(overrideMethodBuilder.length()-1);overrideMethodBuilder.append("){\n");Class returnType = methods[i].getReturnType();if(returnType != Void.class && returnType != void.class)overrideMethodBuilder.append("return (").append(methods[i].getReturnType().getSimpleName()).append(")");overrideMethodBuilder.append("handler.handle(m").append(i).append(",new Object[]{");for(Parameter parameter : parameters){overrideMethodBuilder.append(parameter.getName()).append(",");}if(parameters.length > 0)overrideMethodBuilder.deleteCharAt(overrideMethodBuilder.length()-1);overrideMethodBuilder.append("});\n}");}staticBuilder.append("} catch (NoSuchMethodException e) {\ne.printStackTrace();\n}catch (ClassNotFoundException e) {\ne.printStackTrace();\n}\n");staticBuilder.append("}\n");builder.append(staticBuilder);builder.append("protected $proxy0(MethodInvocationHandler handler) {\nsuper(handler);\n}\n");builder.append(overrideMethodBuilder);builder.append("\n}");System.out.println(builder);return builder.toString();}//    public static void main(String[] args) {
//        generateProxyClass(Seller.class);
//    }
}

這個(gè)類完成了自動(dòng)創(chuàng)建類源碼的功能,其實(shí)現(xiàn)的思路就是將一個(gè)代理類中的特定類利用反射和object去替換,然后將整個(gè)類寫成字符串放進(jìn)StringBuilder中。

然后是編譯代理類源文件、加載編譯好的代理類(利用類加載器)、編寫創(chuàng)建代理實(shí)例的方法。這些底層就不手寫了。

接下來對(duì)比一下兩種寫法的區(qū)別(這里都實(shí)現(xiàn)jdk自帶的InvocationHandler接口,接口內(nèi)容和上面手寫的MethodInvocationHandler一致,只是方法名字為invoke,我寫的是handle):

手動(dòng)創(chuàng)建ChineseSpeakerProxy(此時(shí)仍然為靜態(tài)代理,因?yàn)榇眍愂窃诰幾g時(shí)明確定義的,并且代理類的代碼是手動(dòng)編寫的。相對(duì)于動(dòng)態(tài)代理,靜態(tài)代理類在運(yùn)行時(shí)不會(huì)自動(dòng)生成,而是在編譯時(shí)就已經(jīng)存在。 ):

public class ChineseSpeakerProxy implements Speaker{private Speaker speaker;private InvocationHandler handler;private static Method method;static {try {method = Speaker.class.getMethod("speak");} catch (NoSuchMethodException e) {throw new RuntimeException(e);}}public ChineseSpeakerProxy(Speaker speaker, InvocationHandler handler) {this.speaker = speaker;this.handler = handler;}@Overridepublic void speak() {try {handler.invoke(speaker,method,null);} catch (Throwable e) {throw new RuntimeException(e);}}
}public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();ChineseSpeakerProxy chineseSpeakerProxy = new ChineseSpeakerProxy(chineseSpeaker, new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {method.invoke(proxy,args);System.out.println("方法增強(qiáng)");return null;}});chineseSpeakerProxy.speak();}

使用jdk自帶的Proxy類靜態(tài)方法創(chuàng)建(動(dòng)態(tài)代理):

public class Test01 {public static void main(String[] args) {ChineseSpeaker chineseSpeaker = new ChineseSpeaker();Speaker ChineseSpeakerProxy = (Speaker) Proxy.newProxyInstance(ChineseSpeaker.class.getClassLoader(), ChineseSpeaker.class.getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("方法增強(qiáng)");method.invoke(chineseSpeaker,args);return null;}});ChineseSpeakerProxy.speak();}

注意:使用Proxy類實(shí)現(xiàn)動(dòng)態(tài)代理的時(shí)候,method.invoke()的第一個(gè)參數(shù)不是形參給的,而是被代理的類對(duì)象! 因?yàn)槭褂?Proxy.newProxyInstance動(dòng)態(tài)生成的代理類會(huì)把代理實(shí)例本身傳遞給 InvocationHandler.invoke方法的 proxy 參數(shù)。因此,如果在 invoke 方法中再次調(diào)用 method.invoke(proxy, args),就會(huì)導(dǎo)致遞歸調(diào)用形成死循環(huán)。

總結(jié)

靜態(tài)代理

寫法一:真實(shí)類和代理類實(shí)現(xiàn)同一個(gè)接口,代理類持有真實(shí)類對(duì)象作為屬性,并在重寫接口方法的時(shí)候調(diào)用其方法,再添加方法增強(qiáng)。

寫法二:如果多個(gè)真實(shí)類需要進(jìn)行的方法增強(qiáng)相同,則可以寫一個(gè)通用的代理類,實(shí)現(xiàn)和寫法一相同。

寫法三:利用反射的思想,代理類持有真實(shí)類對(duì)象屬性,并利用反射拿到方法,重寫的時(shí)候用invoke(),并添加方法增強(qiáng)。

寫法四(進(jìn)階):利用接口(這里自己寫的是MethodInvocationHandler)定義重寫的方法,在代理類中創(chuàng)建接口的實(shí)現(xiàn)類(匿名內(nèi)部類),并通過全參構(gòu)造讓用戶自己傳入真實(shí)類對(duì)象和接口實(shí)現(xiàn)類(并重寫代理方法),調(diào)用實(shí)現(xiàn)類的方法。

動(dòng)態(tài)代理:自動(dòng)創(chuàng)建代理類源碼,然后完成編譯、加載。 代理類在運(yùn)行時(shí)根據(jù)目標(biāo)對(duì)象和增強(qiáng)邏輯動(dòng)態(tài)生成。 在使用的時(shí)候利用Proxy類的靜態(tài)方法newProxyInstance()創(chuàng)建代理類,并 通過 InvocationHandler 接口的 invoke 方法在運(yùn)行時(shí)攔截方法調(diào)用,執(zhí)行增強(qiáng)邏輯。

RESTful風(fēng)格

RESTful風(fēng)格不是標(biāo)準(zhǔn),但是在企業(yè)中經(jīng)常使用RESTful風(fēng)格來完成功能的開發(fā)。

REST = Representational State Transfer(表屬性狀態(tài)轉(zhuǎn)移)

簡單來說就是在編寫Servlet的時(shí)候重寫doGet,doPost,doPut,doDelete實(shí)現(xiàn)增查改刪功能。

Spring IOC

Spring簡介

Spring 是目前主流的 Java 開發(fā)框架,是 Java 世界最為成功的框架。其目的是用于簡化企業(yè)級(jí)應(yīng)用程序開發(fā)的難度和周期,任何 Java 應(yīng)用都可以從 Spring 中受益。Spring 框架還是一個(gè)超級(jí)粘合平臺(tái),除了自己提供功能外,還提供粘合其他技術(shù)和框架的能力。

什么是框架? 框架是一個(gè)半成品,提供了基本的運(yùn)行功能,但具體業(yè)務(wù)實(shí)現(xiàn)需要我們?nèi)ゾ帉憽?/p>

Spring體系結(jié)構(gòu)

在這里插入圖片描述

IOC概念:

IOC全稱為 Inverse Of Control,表示控制反轉(zhuǎn)。指的是程序員使用硬編碼創(chuàng)建的對(duì)象轉(zhuǎn)為由Spring容器來創(chuàng)建,對(duì)于對(duì)象生命周期的控制交給Spring容器來管理。控制反轉(zhuǎn)解決了具有依賴關(guān)系的組件之間的強(qiáng)耦合,使得項(xiàng)目形態(tài)更加穩(wěn)健

依賴注入

DI全稱為Dependency Injection,表示依賴注入。指的是在Spring創(chuàng)建對(duì)象的同時(shí),為其屬性賦值

設(shè)值注入:

創(chuàng)建一個(gè)類:

@Data
public class Student {private String name;private String sex;private int age;private Date birthday;
}

在xml配置文件中利用設(shè)值注入創(chuàng)建對(duì)象:

常見數(shù)據(jù)類型:

<!--application.xml-->
<bean name="stu" class="com.qf.spring.ioc.model.Student"><property name="name" value="張三" /><property name="age" value="20" /><property name="sex" value="" /><!--這里需要注意:日期類型的默認(rèn)格式y(tǒng)yyy/MM/dd--><property name="birthday" value="2021/10/10" />
</bean>

使用:

@Test
public void studentTest(){//應(yīng)用上下文使用的是類路徑下XML文檔作為當(dāng)前應(yīng)用上下文ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");//從上下文中根據(jù)bean的名稱或者ID獲取bean對(duì)象Student stu = context.getBean("stu", Student.class);System.out.println(stu);
}

注意:這里的name雖然是user,但是并不是指的user這個(gè)類,而是指向set方法!(理解為去掉set后的名字)設(shè)值注入本質(zhì)就是通過set方法為屬性注入值。設(shè)值注入必須保證存在無參構(gòu)造,否則將報(bào)錯(cuò)。

注入數(shù)組類型:

spring 提供了 array 標(biāo)簽來進(jìn)行數(shù)組類型的屬性值的注入。

@Data
public class Clazz {private int id;private String name;private Student[] students;
}
<bean name="clazz" class="com.qf.spring.ioc.model.Clazz"><property name="id" value="1" /><property name="name" value="張三" /><property name="students"><array><!--引用數(shù)據(jù)類型 可以使用bean標(biāo)簽創(chuàng)建bean對(duì)象注入值--><!--<bean class=""></bean>--><!--引用數(shù)據(jù)類型 可以使用ref標(biāo)簽引用bean對(duì)象注入值--><ref bean="s" /><ref bean="stu" /><!--常用數(shù)據(jù)類型 可以使用value標(biāo)簽直接注入值--><!-- <value></value>--></array></property>
</bean>

注入集合類型:

List集合

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private String name;private String sex;private int age;private Date birthday;private List<Double> scores;
}
<bean name="stu" class="com.qf.spring.ioc.model.Student"><property name="name" value="張三" /><property name="age" value="20" /><property name="sex" value="" /><!--這里需要注意:日期類型的默認(rèn)格式y(tǒng)yyy/MM/dd--><property name="birthday" value="2021/10/10" /><property name="scores"><list><value>80.0</value><value>90.0</value><value>81.0</value><value>82.0</value></list></property>
</bean><bean name="s" class="com.qf.spring.ioc.model.Student"><!--這里按照順序?yàn)閷傩宰⑷胫?-><constructor-arg index="0" value="李四" /><constructor-arg index="1" value="" /><constructor-arg index="2" value="22" /><constructor-arg index="3" value="2020/05/05" /><constructor-arg index="4"><list><value>80.0</value><value>90.0</value><value>81.0</value><value>82.0</value></list></constructor-arg>
</bean>
Set集合
@Data
public class Person {private String name;private Set<String> friendNames;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李剛" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property>
</bean>
注入Map
@Data
public class Person {private String name;private List<String> friendNames;private Map<String, Object> map;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李剛" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property><property name="map"><map><entry key="hobby" value="聊天" /><entry key="clazz" value-ref="clazz"/></map></property><property name="props"><props><prop key="desc">我很帥</prop><prop key="secret">我有兩個(gè)女朋友</prop></props></property>
</bean>
注入Properties
@Data
public class Person {private String name;private List<String> friendNames;private Properties props;
}
<bean name="p" class="com.qf.spring.ioc.model.Person"><property name="name" value="李剛" /><property name="friendNames"><set><value>李四</value><value>王五</value></set></property><property name="props"><props><prop key="desc">我很帥</prop><prop key="secret">我有兩個(gè)女朋友</prop></props></property>
</bean>
構(gòu)造注入

構(gòu)造注入指的是通過構(gòu)造放入為屬性注入值。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {private String name;private String sex;private int age;private Date birthday;
}
<!--application.xml-->
<bean name="s" class="com.qf.spring.ioc.model.Student"><!--這里按照順序?yàn)閷傩宰⑷胫?-><constructor-arg index="0" value="李四" /><constructor-arg index="1" value="" /><constructor-arg index="2" value="22" /><constructor-arg index="3" value="2020/05/05" />
</bean>
@Test
public void studentConstructorTest(){//應(yīng)用上下文使用的是類路徑下XML文檔作為當(dāng)前應(yīng)用上下文ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");//從上下文中根據(jù)bean的名稱或者ID獲取bean對(duì)象Student stu = context.getBean("s", Student.class);System.out.println(stu);
}

http://www.risenshineclean.com/news/35511.html

相關(guān)文章:

  • 棗莊網(wǎng)站設(shè)計(jì)淘寶指數(shù)在線查詢
  • 手機(jī)做網(wǎng)站怎么做網(wǎng)站快速收錄工具
  • 做游戲小網(wǎng)站是啥重慶百度seo整站優(yōu)化
  • 企業(yè)公司網(wǎng)站管理系統(tǒng)免費(fèi)建站免費(fèi)推廣的網(wǎng)站
  • 在網(wǎng)站插入微博靜態(tài)的網(wǎng)頁出的來到服務(wù)器出不來網(wǎng)站建設(shè)流程圖
  • 創(chuàng)意經(jīng)濟(jì)型網(wǎng)站建設(shè)個(gè)人網(wǎng)站推廣怎么做
  • 直銷軟件網(wǎng)站開發(fā)網(wǎng)站權(quán)重怎么提高
  • 新聞網(wǎng)站建設(shè)項(xiàng)目可行性報(bào)告網(wǎng)站媒體推廣方案
  • 上海門戶網(wǎng)站制推薦友情鏈接
  • 湖南seo丈哥seo博客
  • 返利網(wǎng)站制作最新病毒感染
  • 網(wǎng)站標(biāo)簽名詞搜索排名優(yōu)化軟件
  • 會(huì)python做網(wǎng)站seo優(yōu)化前景
  • 天長企業(yè)網(wǎng)站制作最近的新聞?wù)?/a>
  • 做賭石網(wǎng)站客服的經(jīng)驗(yàn)電子商務(wù)seo實(shí)訓(xùn)總結(jié)
  • 網(wǎng)站做短信接口具體方法正規(guī)的關(guān)鍵詞優(yōu)化軟件
  • 多用戶智能網(wǎng)站建設(shè)源碼洛陽網(wǎng)站seo
  • 聊城開發(fā)區(qū)建設(shè)局網(wǎng)站湖南專業(yè)關(guān)鍵詞優(yōu)化服務(wù)水平
  • 公務(wù)員 做網(wǎng)站 違法網(wǎng)站制作網(wǎng)站推廣
  • 手機(jī)網(wǎng)站改版公司百度關(guān)鍵詞熱度查詢工具
  • 做電影網(wǎng)站模板教學(xué)網(wǎng)站制作設(shè)計(jì)
  • 專做醫(yī)藥中間體的網(wǎng)站今天微博熱搜前十名
  • 幫一個(gè)企業(yè)做網(wǎng)站流程seo線上培訓(xùn)班
  • 效果圖在線制作重慶seo俱樂部
  • Iis 建網(wǎng)站為什么說沒有該用戶seo推廣顧問
  • 做電玩城設(shè)計(jì)的網(wǎng)站關(guān)鍵詞優(yōu)化公司
  • 如何搭建一個(gè)視頻網(wǎng)站互聯(lián)網(wǎng)營銷專業(yè)
  • 如何在公司網(wǎng)站上添加內(nèi)容微信朋友圈產(chǎn)品推廣語
  • 服裝網(wǎng)站建設(shè)與實(shí)現(xiàn)西安seo顧問公司
  • 電商網(wǎng)站開發(fā)平臺(tái)實(shí)驗(yàn)河南搜索引擎優(yōu)化